codeforces1472 F. New Year‘s Puzzle

https://codeforces.com/contest/1472/problem/F

首先我们吧colum离散化,然后对于相邻两个c,他们之间的2*2的矩阵都是可以删除的,对最后的安排结果不会造成影响,那么其实坐标就让他要么差1要么差2

然后再最左边的c的左边和最右边的c的右边一定都是竖着放满的,如果影响到中间是肯定有问题的

最后就从左到右状压dp扫过去就行了,0表示2个都不用向右,1表示上面的放一个横的,要拓展到右边,2表示下面的,3表示上下都向右拓展

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxl=3e5+10;

int n,m,k,cnt,tot,cas,ans;
struct node
{
	int r,c;
}a[maxl];
int b[maxl];
int mp[maxl][3],dp[maxl*2][4];
bool vis[maxl];
char s[maxl];

inline bool cmp(const node &a,const node &b)
{
	return a.c<b.c;
}

inline void prework()
{
	scanf("%d%d",&m,&n);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].r,&a[i].c);
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)
	if(a[i].c==a[i-1].c)
		b[i]=b[i-1];
	else if((a[i].c-a[i-1].c)&1)
		b[i]=b[i-1]+1;
	else
		b[i]=b[i-1]+2;
	for(int i=0;i<=b[n];i++)
	{
		mp[i][1]=mp[i][2]=0;
		for(int j=0;j<4;j++)
			dp[i][j]=0;
	}
	for(int i=1;i<=n;i++)
		mp[b[i]][a[i].r]=1;
	dp[0][0]=1;
	for(int i=1;i<=b[n];i++)
	if(mp[i][1]==0 && mp[i][2]==0)
	{
		dp[i][0]|=dp[i-1][0];
		dp[i][0]|=dp[i-1][3];
		dp[i][2]|=dp[i-1][1];
		dp[i][1]|=dp[i-1][2];
		dp[i][3]|=dp[i-1][0];
	}
	else if(mp[i][1]==0)
	{
		dp[i][0]|=dp[i-1][1];
		dp[i][1]|=dp[i-1][0];
	}
	else if(mp[i][2]==0)
	{
		dp[i][0]|=dp[i-1][2];
		dp[i][2]|=dp[i-1][0];
	}else
		dp[i][0]=dp[i-1][0];
}

inline void mainwork()
{
	
}

inline void print()
{
	puts(dp[b[n]][0]?"YES":"NO");
}

int main()
{
	int t=1;
	scanf("%d",&t);
	for(cas=1;cas<=t;cas++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/112211418