问题来源:
http://cxsjsxmooc.openjudge.cn/test/Y/
描述
有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(i-1, j)、 (i+1, j)、 (i, j-1)、 (i, j+1)上的砖都会改变颜色。请你帮助Bob计算出最少需要涂画多少块砖,才能使所有砖的颜色都变成黄色。
输入
第一行是一个整数n (1≤n ≤15),表示墙的大小。接下来的n行表示墙的初始状态。每一行包含n个字符。第i行的第j个字符表示位于位置(i,j)上的砖的颜色。“w”表示白砖,“y”表示黄砖。
输出
一行,如果Bob能够将所有的砖都涂成黄色,则输出最少需要涂画的砖数,否则输出“inf”。
样例输入
5 wwwww wwwww wwwww wwwww wwwww
样例输出
15
解决代码:
#include<iostream>
#include<math.h>
#include<string>
using namespace std;
int t, n, pow2, num;
int **puzzle;//初始化的二维数组,用于标记墙壁最初时各砖块的颜色
int **press;//二维数组,用于标记墙壁的某个砖块是否需要进行上色
void initialization(int temp, char **tempArray) {
n = temp;
t = 0;
pow2 = pow(2, n);
puzzle = new int*[n + 1];//新创建出一个n+1行,n+2列的二维int数组以实现涂砖块的标记,初始化后的第0行和第0列以及n+1列均为1(即为黄色),此后用该二维数组实现局部枚举以推出整体的情况
press = new int*[n + 1];
for (int i = 0; i <= n; i++) {
puzzle[i] = new int[n + 2];
press[i] = new int[n + 2];
}
for (int i = 0; i < n + 2; i++) {
puzzle[0][i] = 1;
press[0][i] = 0;
}
for (int i = 1; i < n + 1; i++) {
puzzle[i][0] = 1;
puzzle[i][n + 1] = 1;
press[i][0] = 0;
press[i][n + 1] = 0;
for (int j = 1; j < n + 1; j++) {
if (tempArray[i-1][j-1] == 'y')
puzzle[i][j] = 1;
else if (tempArray[i - 1][j - 1] == 'w')
puzzle[i][j] = 0;
}
}
}
int guess() {
int c, r;
num = 0;
for (c = 1; c < n + 1; c++) {
if (press[1][c] == 1)
num++;
}
for (r = 1; r < n; r++)
for (c = 1; c < n+1; c++) {
press[r + 1][c] = (puzzle[r][c] + press[r][c] + press[r - 1][c] + press[r][c - 1] + press[r][c + 1] + 1) % 2;
if (press[r + 1][c] == 1)
num++;
}
for (c = 1; c < n+1; c++)
if ((press[n][c - 1] + press[n][c] + press[n][c + 1] + press[n - 1][c] + 1) % 2 != puzzle[n][c])
return(-1);
return(num);
}
int enumerate() {//局部状态的枚举函数以推出整体状态的情况
int c;
for (c = 1; c < n+1; c++) {
press[1][c] = 0;
}
press[1][1] = -1;
int g = -1;
do {
press[1][1]++;
c = 1;
while (press[1][c] > 1) {
press[1][c] = 0;
c++;
press[1][c]++;
}
g=guess();
t++;
} while (g == -1&&t<=pow2);
if (t <= pow2) {
return num;//当t<=pow2时,说明问题有解,此时返回num,即为问题的解(即刷砖块的次数)
}
else if (t > pow2) {
num = -1;
return num;//返回-1表示此问题无解
}
//该函数需要补全的部分:当函数运行2^n次后函数自动结束并输出inf,否则输出刷砖块的次数
}
int main()
{
int round;
cin>> round;
for (int i = 0; i < round; i++) {
int temp;
cin>> temp;
cin.get();
char** temparr = new char*[temp];
for (int j = 0; j < temp; j++) {
temparr[j] = new char[temp+1];
}
for (int r = 0; r < temp; r++) {
cin.getline(temparr[r],temp+1);
}
initialization(temp, temparr);
enumerate();
if (num == -1)
cout << "inf" << endl;
else
cout << num << endl;
}
return 0;
}
P.S. 改代码可以成功通过POJ的测试,但是在Course上无法通过,若想在Course上通过需要对Main函数进行修改