您的位置:首页 > 编程语言

POJ 算法基础 Assignment: 编程作业—枚举 编程题#1: 画家问题

2015-09-16 19:55 330 查看

编程题#1: 画家问题

来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩。)

注意: 总时间限制: 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


#include <iostream>
#include <math.h>
using namespace std;
int guess(int *puzzle, int *press,int i)
{
int c, r, count = 0;
for (c = 1; c < i+1; ++c) {
if (press[(i+2)+c] == 1) count++;
}
for (r=1; r< i; r++) {
for (c = 1; c < i+1; ++c) {
// 跟踪puzzle第一行,计算press其他行的值
press[(r + 1)* (i+2) +c] = (puzzle[r*(i+2)+c] + press[r*(i+2)+c] + press[(r - 1)*(i+2)+c]
+ press[r*(i+2)+c - 1] + press[r*(i+2)+c + 1]) % 2;
if (press[(r + 1)* (i+2) +c] == 1) count++;
}
}
for (c=1; c < i + 1; c++) {
if ((press[i*(i+2)+c - 1] + press[i*(i+2)+c] + press[i*(i+2)+c + 1] +
press[(i - 1)*(i+2)+c]) % 2 != puzzle[i*(i + 2)+c]) {
return -1; // 返回-1标示该press的第一行不能使地板全变黄
}

}
return count;//如果能使地板全变黄,返回该办法所需涂的地砖的个数
}

int enumerate (int *puzzle, int *press,int i)
{
int c, sum = -1,n= (int)pow(2,i);
for ( c=1; c<i+1; c++) {
press[(i+2)+c] = 0;
}
if (guess(puzzle, press, i) != -1) {
sum = guess(puzzle, press, i);
}
while (n--) {
press[(i+2)+1]++;
c = 1;
while (press[(i+2)+c] > 1) {
press[(i+2)+c] = 0;
c++;
press[(i+2)+c]++;
}
if (guess(puzzle, press, i) != -1) {
if (sum == -1) {
sum = guess(puzzle, press, i);
} else if (guess(puzzle, press, i) < sum) {
sum = guess(puzzle, press, i);
}
}
}
return sum;
}

int main()
{
int cases,i;
cin>>cases;
while (cases--) {
cin>>i;
if (i == 1) {
char t;
cin >> t;
if (t == 'w') {
cout<<1<<endl;
} else {
cout<<0<<endl;
}
} else {
int *puzzle, *press;
puzzle = new int[(i+2)*(i+2)];//初始数组
press = new  int[(i+2)*(i+2)];//按下状态,按下为1,未操作为0
//初始化press数组
int c, r;
for (r=0; r<i+1; r++) {
press[r*(i+2)] = press[r*(i+2)+i+1] = 0;
}
for (c=1; c<i+1; c++) {
press[c] = 0;
}
//输入数据
for(r=1; r<i+1; r++) {
for(c=1; c<i+1; c++) {
char t;
cin >> t;
if (t == 'w') {
puzzle[r*(i+2)+c] = 1;
} else {
puzzle[r*(i+2)+c] = 0;
}
}
}
int result = enumerate(puzzle,press,i);
if (result == -1) {
cout<<"inf"<<endl;
} else {
cout<<result<<endl;
}
}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: