题意: 有一个长度为n宽度为2的格子,其中有一些位置有阻碍,问剩下的位置能否用1*2的木块填满,
T组1e4
n 1e9
∑
m
≤
2
e
5
\sum m \leq 2e5
∑m≤2e5
题解: 老模拟带师了
由于题目保证的是m的数量,(即阻碍的数量,所以从这里下手
可以贪心的得到:如果第一列是没有阻碍的,竖直放置木块,可以删去这一列,如果第一列的阻碍为2也可以删去第一列,(相当于第一列后移)否则必须横着放置木块,
前两种情况过后,第一列必是有且仅有一个阻碍的情况
观察下一个有阻碍的列,如果该列有两个阻碍,则不成立(中间的空位为奇),判断阻碍所在的位置与目前的第一列阻碍所在的位置能否有解,若有解则删去这些列,第一列后移
有一个阻碍的列两两为一组,观察阻碍所在的上下位置和列号的奇偶性判断是否合法
特判如果扫完了还是有落单的,说明也无解
code:
#include <bits/stdc++.h>
using namespace std;
map<int,int > mp;
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int T;
cin >> T;
while(T--) {
mp.clear();
int n, m;
cin >> n >> m;
int x, y;
for(int i = 0; i < m; ++ i) {
cin >> x >> y;
mp[y] = mp[y] | x;
}
bool flag = 0;
int nwf = 0, prenum = 0;
bool havepre = 0;
for(auto item : mp) {
int x = item.first;
int num = item.second;
if(num == 3) {
if(!havepre) continue;
else {
flag = 1;
break;
}
}
else {
if(!havepre) {
havepre = 1;
prenum = num;
nwf = x;
}
else {
havepre = 0;
if(num == prenum) {
if((x - nwf) & 1) {
continue;
}
flag = 1;
break;
}
else {
if(!((x - nwf) & 1)) {
continue;
}
flag = 1;
break;
}
}
}
}
if(flag || havepre) cout << "NO\n";
else cout << "YES\n";
}
}