编程题#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__()