Codeforces Round #693 (Div. 3) 全文见:https://blog.csdn.net/qq_43461168/article/details/112596814
F. New Year’s Puzzle
题意:给定一个2*n的矩形。不过有一些块被ban掉了。然后用 2*1 和 1*2 的砖头把他铺满。问能否铺满。![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0512b9b53f46cbb07653ebcf9b8ab446.png)
思路:其实就一个分类讨论的题。先对黑块排个序。然后遍历。分很多种情况。先假设 up = 1表示 底下是黑块,而上面放了一个躺着的块。 down = 1表示下面放了一个躺着的块。来表示两种状态。用 last 表示 上一个黑块的位置 如图:
然后分类讨论了。
1. 上下都是黑块。那前面必须 down 和 up 都为0才行。也就是不会能铺满2*k的格子而不会凸出来一个。
2. 上面是黑块。有五种情况,第一种就是down 和 up 都为0,那么必须放一个躺着的,剩下的情况:中间的白块数量只是代表距离的奇偶性。
3. 下面是黑块。有五种情况,第一种同上就是down 和 up 都为0,那么必须放一个躺着的,剩下的情况。 和上面一样分析。 倒过来就行了。
AC代码:
#include <iostream>
#include <bits/stdc++.h>
#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int N = 1e6+7;
int n,m,k,t = 1,cas = 1;
//int a[N],b[N];
struct node{
int x,y;
}a[N];
bool cmp(node a1,node a2){
return a1.y < a2.y;
}
signed main(){
cin>>t;
while(t--){
cin>>n>>m;
int maxx = 0;
for(int i = 0 ; i < m ; i ++){
cin>>a[i].x>>a[i].y;
maxx = max(a[i].y,maxx);
}
a[m].x = 1,a[m++].y = maxx+1;
a[m].x = 2,a[m++].y = maxx+1;
sort(a,a+m,cmp);
int up = 0;
int down = 0;
int flag = 1;
int last = 0;
for(int i = 0; i < m ; i ++){
//cout<<a[i].x<<" "<<a[i].y<<" "<<up<<" "<<down<<endl;
if((i+1) < m && a[i+1].y == a[i].y){
if(up || down){
flag = 0;
break;
}
i ++;
}else if(a[i].x == 1){
int dis = a[i].y - last - 1;
if(dis%2){ // 距离为奇数
if(down == 0 && up == 0){
down = 1;
}else if(down){
flag = 0;
break;
}else{
up = 0;
down = 0;
}
}else{ // 距离为偶数
if(down == 0 && up == 0){
down = 1;
}else if(down){
up = 0;
down = 0;
}else{
flag = 0;
break;
}
}
}else{
int dis = a[i].y - last - 1;
if(dis%2){ // 距离为奇数
if(up == 0 && down == 0){
up = 1;
}else if(up){
flag = 0;
break;
}else{
up = 0;
down = 0;
}
}else{ // 距离为偶数
if(up == 0 && down == 0){
up = 1;
}else if(up){
down = 0;
up = 0;
}else{
flag = 0;
break;
}
}
}
last = a[i].y;
}
puts(flag ? "YES" : "NO");
}
}