mayoko’s diary

プロコンとかいろいろ。

yukicoder No.274 The Wall

寝オチして参加できなかった yukicoder。

解法

貪欲で解けます。

まず, 左端のブロックが一番左に寄るようにします。そのためにブロックを回転させるかさせないかを選びます。

で, ブロックは一番左端のブロックの座標が小さいものから詰めていきます。
もし左端からブロックを詰められるなら, 左側からブロックを詰め, ダメなら 180 度回転してブロックを詰めていきます。

const int MAXN = 2020;
const int MAXM = 4020;

int L[MAXN], R[MAXN];
int N, M;

bool solve(const vector<pii>& walls) {
    int l = 0, r = M-1;
    for (auto p : walls) {
        if (p.first >= l) {
            if (p.second > r) {
                return false;
            }
            l = p.second+1;
        } else if (M-p.first-1 <= r) {
            if (M-p.second-1 < l) {
                return false;
            }
            r = M-p.second-2;
        } else return false;
    }
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> N >> M;
    vector<pii> walls;
    for (int i = 0; i < N; i++) {
        cin >> L[i] >> R[i];
        if (L[i] <= M-R[i]-1) walls.emplace_back(L[i], R[i]);
        else walls.emplace_back(M-R[i]-1, M-L[i]-1);
    }
    sort(walls.begin(), walls.end());
    cout << (solve(walls) ? "YES" : "NO") << endl;
    return 0;
}