A:画家问题
总时间限制:
1000ms
内存限制:
65536kB
描述
有一个正方形的墙,由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
========================================================================
eg.
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int t = 0;
int n = 0;
char col[20];
bool c[20][20] = {0};
bool colored[20][20] = {0};
bool swit[20][20] = {0};
void changeswit(int a, int b)
{
colored[a][b] = !colored[a][b];
colored[a - 1][b] = !colored[a - 1][b];
colored[a + 1][b] = !colored[a + 1][b];
colored[a][b - 1] = !colored[a][b - 1];
colored[a][b + 1] = !colored[a][b + 1];
}
int main()
{
scanf("%d", &t);
for(int ti = 1; ti <= t; ++ti)
{
int sum = 0;
scanf("%d", &n);
int min = n * n + 1;
for(int i = 1; i <= n; ++i)
{
scanf("%s", col);
for(int j = 1; j <= n; ++j)
{
if(col[j - 1] == 'y') c[i][j] = 1;
else c[i][j] = 0;
}
}
for(int k = 0; k < pow(2.0, n); k++)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
colored[i][j] = c[i][j];
}
for(int i = 1; i <= n; i++)
{
swit[1][i] = (k>>(i - 1)) & 1;
if(swit[1][i])
{
changeswit(1, i);
sum++;
}
}
for(int i = 2; i <= n; i++)
for(int j = 1; j <= n; j++)
if(!colored[i - 1][j])
{
swit[i][j] = 1;
sum++;
changeswit(i, j);
}
int mark = 0;
for(int j = 1; j <= n; j++)
if(!colored[n][j]) mark = 1;
if(!mark && sum < min) min = sum;
sum = 0;
}
if(min != n*n + 1) printf("%d\n",min);
else printf("inf\n");
}
return 0;
}