有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(i-1, j)、 (i+1, j)、 (i, j-1)、 (i, j+1)上的砖都会改变颜色。请你帮助Bob计算出最少需要涂画多少块砖,才能使所有砖的颜色都变成黄色。
第一行是个整数t(1≤t ≤20),表示要测试的案例数。然后是t个案例。每个案例的首行是一个整数n (1≤n ≤15),表示墙的大小。接下来的n行表示墙的初始状态。每一行包含n个字符。第i行的第j个字符表示位于位置(i,j)上的砖的颜色。“w”表示白砖,“y”表示黄砖。
每个案例输出一行。如果Bob能够将所有的砖都涂成黄色,则输出最少需要涂画的砖数,否则输出“inf”。
2 3 yyy yyy yyy 5 wwwww wwwww wwwww wwwww wwwww
0 15
要解决这个问题,我们先去思考一下,怎么涂才能把全部区块涂满呢?又有多少种的解法?显然,我们没有办法直接一眼就看出来怎么去涂,并且题目也要求我们去求一个最少的操作步骤,所以枚举是不可避免的,关键是我们如何去枚举呢?
其实我们一行一行地涂,考虑第一行每一个区块是否涂就可以了,后面的每一行都是根据前一行的状态去确定是否填涂的,如果前一行中有白色的砖块,那么它的下一行的这个砖块必然要涂,否则不可能把全部砖块都涂满,这样的话问题就清晰起来了,其实我们只要去枚举第一行的全部情况即可,每个方块只有涂和不涂两种状态,所以说,最多也就2的15次方种情况,这是一个可以接受的数字。
最后只要检查最后一行有没有被涂满就行了。
#include <iostream>
#include <cstring>
using namespace std;
int t=0,n=0,ANS=1e9;;
char board1[16][16],board2[16][16];
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
bool is[16]={0}, count[16][16];
void draw(int x,int y){
if(board2[x][y]=='w') board2[x][y]='y';
else board2[x][y]='w';
for(int i=0;i<4;i++){
int nx=x+dx[i],ny=y+dy[i];
if(nx>=1 && nx<=n && ny>=1 && ny<=n){
if(board2[nx][ny]=='w') board2[nx][ny]='y';
else board2[nx][ny]='w';
}
}
}
void print(int row){
if(row==n+1){
for(int i=1;i<=n;i++){
if(board2[n][i]=='w'){
return;
}
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(count[i][j]) ans++;
}
ANS=min(ANS,ans);
return;
}
if(row==1){
for(int i=1;i<=n;i++){
if(is[i]){
draw(row,i);
count[row][i]=1;
}
}
print(row+1);
}
else{
for(int i=1;i<=n;i++){
if(board2[row-1][i]=='w'){
draw(row,i);
count[row][i]=1;
}
}
print(row+1);
}
}
void fill(int step){
if(step==n+1){
memcpy(board2,board1,sizeof(board1));
memset(count,0,sizeof(count));
print(1);
return;
}
for(int i=0;i<2;i++){
if(i==0){
is[step]=1;
fill(step+1);
}
else{
is[step]=0;
fill(step+1);
}
}
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf(" %c",&board1[i][j]);
}
}
memset(is,0,sizeof(is));
ANS=1e9;
fill(1);
if(ANS!=1e9)
printf("%d\n",ANS);
else
printf("inf\n");
}
return 0;
}