编程题#1: 画家问题
描述
有一个正方形的墙,由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”
Analysis:
枚举墙的第一行所有列的涂画情况,依此推断下一行的的涂画情况(使每行的墙都被涂画成黄色)直到最后一行,然后check最后一行的墙是否能被涂成黄色。
实现代码如下:
#include<iostream>
using namespace std;
int wallColor[16][17] = {0};
int paint[16][17] = {0};
int trys(int &wallSize){
int row,col;//画板的行和列
/*根据画板颜色和周围paint颜色值判断下一行paint的颜色值*/
for(row=1; row<wallSize;row++){
for(col=1;col<=wallSize;col++){
paint[row+1][col]= (wallColor[row][col]+paint[row-1][col]+
paint[row][col-1]+paint[row][col]+paint[row][col+1])%2;
}
}
//判断最后一行能否被画成黄色
for(col=1;col<=wallSize;col++){
if(wallColor[wallSize][col]!=(paint[wallSize-1][col]+paint[wallSize][col-1]
+paint[wallSize][col]+paint[wallSize][col+1])%2){
return 400;
}
}
//计算所需的次数
int steps=0;
for(row=1;row<=wallSize;row++){
for (col=1;col<=wallSize;col++){
if(paint[row][col]==1){
steps++;
}
}
}
return steps;
}
//枚举第一行的所有情况
int enumerate(int &wallSize){
int minsteps=400;
int steps=0;
while(paint[1][wallSize+1]<1){
steps=trys(wallSize);
if (steps<minsteps){
minsteps=steps;
}
paint[1][1]++;
int c=1;
while(paint[1][c]>1){
paint[1][c]=0;
c++;
paint[1][c]++;
}
}
return minsteps;
}
int main(){
int t,n,c,r;
int minsteps;
cin>>t;
for (int k=0;k<t;k++){
//初始化画板颜色
for(r=0;r<16;r++){
for(c=0;c<17;c++){
wallColor[r][c]=0;
paint[r][c]=0;
}
}
//输入颜色并将颜色转换为数字 0 or 1
cin>>n;
for(r=1;r<n+1;r++){
for(c=1;c<n+1;c++){
char color;
cin>>color;
wallColor[r][c]=color=='y'?0:1;
}
}
minsteps=enumerate(n);
if (minsteps==400){
cout<<"inf"<<endl;
}
else{
cout<<minsteps<<endl;
}
}
}
Python版本:
wallColor = [[0 for i in range(17)] for i in range(16)] paint = [[0 for i in range(17)] for i in range(16)] def trys(wallSize): for row in range(wallSize)[1:]: for col in range(wallSize+1)[1:]: paint[row+1][col] = (wallColor[row][col] + paint[row-1][col] + paint[row][col-1] + paint[row][col] + paint[row][col+1])%2 for col in range(wallSize+1)[1:]: if (wallColor[wallSize][col]!=(paint[wallSize-1][col]+paint[wallSize][col-1] +paint[wallSize][col]+paint[wallSize][col+1])%2): return 400 steps = 0 for row in range(wallSize+1)[1:]: for col in range(wallSize+1)[1:]: if paint[row][col] == 1: steps+=1 return steps def enumerate(wallSize): minsteps = 400 steps = 0 while(paint[1][wallSize]<1): steps = trys(wallSize) if (steps<minsteps): minsteps = steps paint[1][1] += 1 c = 1 while(paint[1][c]>1): paint[1][c] = 0 c += 1 paint[1][c]+=1 return minsteps def __main__(): t = int(input()) for k in range(t): for r in range(16): for c in range(17): wallColor[r][c] = 0 paint[r][c] = 0 n = int(input()) for r in range(n+1)[1:]: for c in range(n+1)[1:]: color = chr(input()) if color == 'y': wallColor[r][c] = 0 else: wallColor[r][c] = 1 minsteps = enumerate(n) if (minsteps == 400): print ('inf') else: print minsteps __main__()