Description
有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白->黑)时,其周围上下左右(如果存在的话)的格子的颜色也被反转,问至少反转几个格子可以使4*4的正方形变为纯白或者纯黑
Input
每个格子初始状态的颜色,’w’表示白色,‘b’表示黑色
Output
最少反转次数
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
Solution
因为最后格子状态只能为全黑或全白,以将格子变成全黑为例,首先枚举第一行的反转情况,然后一行行向下递推,后面格子的反转必须使得前一行格子变成黑色,这样一来当将第四行反转完后前三行都为黑色,这时只需判断第四行是否全黑即可,对于每次满足条件的枚举枚举更新最小反转次数
Code
#include<stdio.h>
#define min(x,y) x<y?x:y
char chess[4][5],chesss[4][5];
int count=0;
void returns(int x,int y)//反转(x,y)
{
count++;//反转次数加一
int dx[5]={-1,0,1,0,0},dy[5]={0,-1,0,1,0};//需反转的五个格子
int nx,ny,i;
for(i=0;i<5;i++)
{
nx=x+dx[i];
ny=y+dy[i];
if(nx>=0&&nx<4&&ny>=0&&ny<4&&chesss[nx][ny]=='b')//黑变白
chesss[nx][ny]='w';
else if(nx>=0&&nx<4&&ny>=0&&ny<4&&chesss[nx][ny]=='w')//白变黑
chesss[nx][ny]='b';
}
}
int main()
{
int i,j,k,s1,s2,s3,s4,min=100;
for(i=0;i<4;i++)
for(j=0;j<=4;j++)
scanf("%c",&chess[i][j]);
for(s1=0;s1<=1;s1++)//将格子变成全白
for(s2=0;s2<=1;s2++)
for(s3=0;s3<=1;s3++)
for(s4=0;s4<=1;s4++)
{
for(i=0;i<4;i++)//对复制棋盘进行反转操作
for(j=0;j<=4;j++)
chesss[i][j]=chess[i][j];
count=0;//初始化
if(s1==1)returns(0,0);//0表示不反转,1表示反转
if(s2==1)returns(0,1);
if(s3==1)returns(0,2);
if(s4==1)returns(0,3);
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(chesss[i][j]=='b')//如果正在处理的格子上方不是白色则反转该格子
returns(i+1,j);
if(chesss[3][0]=='w'&&chesss[3][1]=='w'&&chesss[3][2]=='w'&&chesss[3][3]=='w')//第四行全白
min=min(min,count);//更新反转次数最小值
}
for(s1=0;s1<=1;s1++)//将格子变成全黑
for(s2=0;s2<=1;s2++)
for(s3=0;s3<=1;s3++)
for(s4=0;s4<=1;s4++)
{
for(i=0;i<4;i++)//对复制棋盘进行反转操作
for(j=0;j<=4;j++)
chesss[i][j]=chess[i][j];
count=0;//初始化
if(s1==1)returns(0,0);//0表示不反转,1表示反转
if(s2==1)returns(0,1);
if(s3==1)returns(0,2);
if(s4==1)returns(0,3);
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(chesss[i][j]=='w')//如果正在处理的格子上方不是黑色则反转该格子
returns(i+1,j);
if(chesss[3][0]=='b'&&chesss[3][1]=='b'&&chesss[3][2]=='b'&&chesss[3][3]=='b')//第四行全黑
min=min(min,count);//更新反转次数最小值
}
if(min!=100) printf("%d\n",min);
else printf("Impossible\n");
}