CF1472F 题解

前言

只要题目给了图,你就要画图。

思路

首先,我们要明确一点:一个矩形,如果里面不存在任何被覆盖的方格,那么这个矩形是绝对可以被覆盖的。

如果现在有一个点被覆盖了。

pFmwFzR.png

那么必定要有一个长方形从这个点下方往后。

然后继续在上方接长方形继续往后。

pFmw1SA.md.png

直到出现了一个新节点被覆盖。

假设在新节点的上一个点之前,都是可以被完全覆盖的。

如果在同一行。

  • 两个点之间的距离为偶数,那么这之间肯定可以被盖住。然后继续往后找。

pFmw5lR.md.png

  • 如果为奇数,稍加思考,可以证明这一段是不能被完全盖住的,直接跳出,无解。

接下来考虑不在同一行。

  • 两个点之间的距离为奇数,那么这之间一定可以被完全盖住。

pFm0KBV.md.png

  • 两个点之间的距离为偶数,思考一下,能证明不能被完全盖住,跳出,无解。

  • 两个点在同一列,如果前面还有点未找到对应点,也无解。

如果前面不能被完全盖住,那么会提前跳出,所以如果能到这里,那么前面一定合法。

最后,如果上一个点之后没有找到对应的下一个点,也无解。

在代码实现中,注意我们要将点排序。接着用一个变量记录前面是否还有未处理完的点,有则判断当前点与之前点是否合法,没有就把变量赋为 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;
}
posted @ 2024-01-28 21:43  Xu_dh  阅读(15)  评论(0)    收藏  举报