1. 程式人生 > 其它 >cf1472 F. New Year's Puzzle

cf1472 F. New Year's Puzzle

題意:

\(2*n\) 網格,某些格子被 ban 了。現有無數的 \(1*2\)\(2*1\) 瓷磚,問能不能覆蓋所有未 ban 的格子。

被 ban 的和範圍外的格子不能被覆蓋,未 ban 的每個格子只能被覆蓋一次

思路:

滿腦子國際象棋棋盤染色,沒想到是個分類討論模擬。。。

考慮最左邊的列,

如果已滿(上下兩格都已被覆蓋),刪除這列,第二列變成新的第一列;

如果為空就豎著放,然後同樣刪除此列。這是因為如果第二列滿,那隻能放一個豎的;如果第二列為空,前兩列要麼放倆豎要麼放倆橫,不妨就放倆豎;如果第二列有一個,那隻能在第一列放一豎,然後接著處理第二列;

如果有一個,那必定要往下一列伸出一格(程式碼中用 \(out\)

變數記錄),然後也是刪除第一列,這時第二列被改變了,與初始不同。當然這個過程如果衝突就寄了

void sol() {
    int n, m; cin >> n >> m;
    map<int,int> mp; //-1表示滿
    while(m--) {
        int r, c; cin >> r >> c;
        mp[c] = mp[c] ? -1 : r;
    }
    int last = 0, out = 0; //前面伸過來的
    for(auto &[p, st]: mp) {
        if(last && out && (p-last)%2==0) out = 3 - out; last = p;
        if(out) {
            if(st != -1 && st != out) out = 0;
            else return cout << "NO\n", void();
        }
        else if(st != -1) out = 3 - st;
    }
    cout << (out ? "NO\n" : "YES\n");
}