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");
}

浙公网安备 33010602011771号