Problem : 翻棋子
Description
有一个4*4的棋盘,放有16枚棋子。
每个棋子都是一面黑一面白,一开始有的黑面朝上,有的白面朝上。
下面是一个例子,这个例子用文字描述为:
bwbw
wwww
bbwb
bwwb
我们可以任选一个棋子,把它自己和它的相邻棋子(上下左右,如果有的话)翻面。
比如在例子中如果我们选第3行第1列的棋子翻面,布局就变成如下:
bwbw
bwww
wwwb
wwwb
题目
求出能把所有棋子都翻成白色或都黑色的最少的步数。
Input
4行每行4个字符,可能是b(黑)或w(白)
Output
一个数,最少步数。如果无解输出Impossible
Sample Input
bwbw
wwww
bbwb
bwwb
Sample Output
Impossible
#include<iostream>
using namespace std;
bool map[16][16]= {false};
bool flag=false;
int st;
int a[6]= {-1,1,0,0,0},b[6]= {0,0,-1,1,0};
bool panduan()
{
for(int i=1; i<=4; i++)
for(int j=1; j<=4; j++)
{
if(map[i][j]!=map[1][1])
return false;
}
return true;
}
void f(int r,int c)
{
for(int i=0; i<=4; i++)
map[r+a[i]][c+b[i]]=!map[r+a[i]][c+b[i]];
return;
}
void dfs(int r,int c, int deep)
{
if(deep==st)
{
flag=panduan();
return;
}
if(flag||r==5) return;
f(r,c);
if(c<4)
dfs(r,c+1,deep+1);
else
dfs(r+1,1,deep+1);
f(r,c);
if(c<4)
dfs(r,c+1,deep);
else
dfs(r+1,1,deep);
return;
}
int main()
{
char fi;
for(int i=1; i<=4; i++)
for(int j=1; j<=4; j++)
{
cin>>fi;
if(fi=='b') map[i][j]=true;
}
for(st=0; st<=16; st++)
{
dfs(1,1,0);
if(flag) break;
}
if(flag)
cout<<st<<endl;
else
cout<<"Impossible"<<endl;
return 0;
}