#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int map[16][16], temp[16][16], row[16];
int n, min, cnt;
void meiju(int x)//枚舉所有繪畫情況
{
memset(row, 0, sizeof(row));
int i = 0;
while(x)
{
row[i++] = x&1;
x >>= 1;
}
}
void paint(int x,int y)//畫一格
{
temp[x][y] = !temp[x][y];
if(x-1 >= 0)
temp[x-1][y] = !temp[x-1][y];
if(y-1 >= 0)
temp[x][y-1] = !temp[x][y-1];
if(x+1 < n)
temp[x+1][y] = !temp[x+1][y];
if(y+1 < n)
temp[x][y+1] = !temp[x][y+1];
cnt++;
}
void check()//根據第一行進行暴力檢查
{
//如果上一行的當前列不是黃色則對當前行當前列進行繪畫
for(int i = 1; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
if(temp[i-1][j] != 1)
paint(i,j);
}
}
//檢查經過繪畫後的最後一行是否全爲黃色
for(int i = 0; i < n; ++i)
{
if(temp[n-1][i] != 1)
return; //不全爲黃色說明此種繪畫方法失敗
}
if(min > cnt) //成功則保存最小的次數
min = cnt;
}
int main()
{
int i, j, k, t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
min = n*n + 1; //求出畫的最小次數
char s[16];
for(i = 0; i < n; ++i)//輸入字符
{
scanf("%s", s);
for(j = 0; j < n; ++j)
{
if(s[j] == 'w') //白色標記爲0
map[i][j] = 0;
else
map[i][j] = 1;
}
}
k = pow(2.0,n); //枚舉第一行所有畫的情況
for(i = 0; i < k; ++i)
{
meiju(i);
cnt = 0; //初始化
memcpy(temp, map, sizeof(map));
for(j = 0; j < n; ++j) //畫出第一行
{
if(row[j] == 1)
paint(0,j);
}
check();
}
if(min == n*n+1)
printf("inf\n");
else
printf("%d\n", min);
}
return 0;
}
題意:給出一個畫板,畫板上有n*n個格子,初始狀態上隨機格數黃色和白色,可以對其中一個格子進行變色,每進行一次變色該格子的上下左右四個格子都需要變色,問需要多少次變色可使所有格子變成黃色,若有多種可能取次數最小的,若無可能則輸出inf。
思路:對第一行所有可能的變色情況進行枚舉,然後根據第一行的顏色逐行推出下一行的變色情況,最後判斷最後一行的顏色是否全爲黃色,如果是則說明可行,保存最小的次數。