题目大意
给定一个带有 R
,W
和 .
的 \(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;
}