CF1534A Colour the Flag 题解

题目传送门

题目大意

给定一个带有 RW.\(n\)\(m\) 列的字符矩阵。
请你将所有 . 的位置换成 R 或者 W,要求最终每个 R 的位置上下左右没有 R,每个 W 的位置上下左右没有 W
如果做不到,输出 NO
否则输出 YES,并且输出方案。

题目解析

显然我们发现,所有的 R 的四周全部是 W,所有的 W 四周全是 R,那么大致就成了一张网格状的矩阵,大概长这样:

WRWRWRWRWRWRWRWR
RWRWRWRWRWRWRWRW
WRWRWRWRWRWRWRWR
RWRWRWRWRWRWRWRW
WRWRWRWRWRWRWRWR
RWRWRWRWRWRWRWRW

或者是这样:

RWRWRWRWRWRWRWRW
WRWRWRWRWRWRWRWR
RWRWRWRWRWRWRWRW
WRWRWRWRWRWRWRWR
RWRWRWRWRWRWRWRW
WRWRWRWRWRWRWRWR

我们发现,两种形式每个位置的颜色都不同,那么只要确定一个就能确定这是哪张图,然后就能确定其他的所有了。

当然不难发现,两种形式中任意一个都有以下性质:
同种颜色的横纵坐标之和的奇偶性相同,不同种颜色的横纵坐标之和的奇偶性不同。

代码:

#include<cstdio>
#define maxn 139
using namespace std;
//#define debug
typedef int Type;
inline Type read(){
	Type sum=0;
	int flag=0;
	char c=getchar();
	while((c<'0'||c>'9')&&c!='-') c=getchar();
	if(c=='-') c=getchar(),flag=1;
	while('0'<=c&&c<='9'){
		sum=(sum<<1)+(sum<<3)+(c^48);
		c=getchar();
	}
	if(flag) return -sum;
	return sum;
}
int T,n,m,a[maxn][maxn];
int flag,c;
int check(){
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=m;j++){
	    	if(a[i][j]){
	    		if(flag==-1) flag=(i+j+a[i][j])%2;
				else{
					if(flag==(i+j+a[i][j])%2);
					else return 0;
				}
			}
		}
	return 1;
}
int main(){
	//freopen(".in","r",stdin);
	//freopen("1.out","w",stdout);
    T=read();
    while(T--){
    	flag=-1;
    	n=read(); m=read();
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=m;j++){
    	    	c=getchar();
    	    	while(c!='R'&&c!='.'&&c!='W') c=getchar();
    	    	if(c=='R') a[i][j]=1;
    	    	else if(c=='W') a[i][j]=2;
    	    	else a[i][j]=0;
			}
		if(check()){
			if(flag==-1) flag=0;
			printf("YES\n");
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++)
				    if((i+j)%2==flag) putchar('W');
				    else putchar('R');
				putchar('\n');
			}
		}
		else printf("NO\n");
	}
	return 0;
}
posted @ 2021-06-16 15:40  jiangtaizhe001  阅读(130)  评论(0编辑  收藏  举报