前言
只要题目给了图,你就要画图。
思路
首先,我们要明确一点:一个矩形,如果里面不存在任何被覆盖的方格,那么这个矩形是绝对可以被覆盖的。
如果现在有一个点被覆盖了。
那么必定要有一个长方形从这个点下方往后。
然后继续在上方接长方形继续往后。
直到出现了一个新节点被覆盖。
假设在新节点的上一个点之前,都是可以被完全覆盖的。
如果在同一行。
- 两个点之间的距离为偶数,那么这之间肯定可以被盖住。然后继续往后找。
- 如果为奇数,稍加思考,可以证明这一段是不能被完全盖住的,直接跳出,无解。
接下来考虑不在同一行。
- 两个点之间的距离为奇数,那么这之间一定可以被完全盖住。
-
两个点之间的距离为偶数,思考一下,能证明不能被完全盖住,跳出,无解。
-
两个点在同一列,如果前面还有点未找到对应点,也无解。
如果前面不能被完全盖住,那么会提前跳出,所以如果能到这里,那么前面一定合法。
最后,如果上一个点之后没有找到对应的下一个点,也无解。
在代码实现中,注意我们要将点排序。接着用一个变量记录前面是否还有未处理完的点,有则判断当前点与之前点是否合法,没有就把变量赋为 1,继续考虑下一个。
AC CODE
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct M{
int x,y;
}a[200005];
inline bool cmp(M x,M y){
return x.y<y.y;
}
int main(){
int T;
cin>>T;
while(T--){
cin>>n>>m;
memset(a,0,sizeof a);
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].y;
}
sort(a+1,a+m+1,cmp);
bool ok=1,fg=0;
for(int i=1;i<=m;i++){
if(a[i].y==a[i+1].y){
if(fg){
ok=0;
break;
}
i++;
}
else{
if(fg){
if(a[i-1].x==a[i].x){
if((a[i].y-a[i-1].y-1)%2==0){
fg=0;
}
else{
ok=0;
break;
}
}
else{
if((a[i].y-a[i-1].y-1)%2==1){
fg=0;
}
else{
ok=0;
break;
}
}
}
else{
fg=1;
}
}
}
if(!ok||fg)puts("NO");
else puts("YES");
}
return 0;
}
标签:那么,一个点,覆盖,int,题解,盖住,如果,CF1472F
From: https://www.cnblogs.com/xdh2012/p/17993482