描述
有一个4*4的棋盘,放有16枚棋子。每个棋子都是一面黑一面白,一开始有的黑面朝上,有的白面朝上。下面是一个例子,这个例子用文字描述为:
bwbw
wwww
bbwb
bwwb
我们可以任选一个棋子,把它自己和它的相邻棋子(上下左右,如果有的话)翻面。比如在例子中如果我们选第3行第1列的棋子翻面,布局就变成如下:
bwbw
bwww
wwwb
wwwb
题目
求出能把所有棋子都翻成白色或都黑色的最少的步数。
输入输出格式
输入
4行每行4个字符,可能是b(黑)或w(白)
输出
一个数,最少步数。如果无解输出Impossible
输入输出样例
输入样例1
bwbw wwww bbwb bwwb
输出样例1
Impossible
解题思路
每一颗棋子都有翻与不翻两种情况,总共有4*4=16个棋子,总共有2^16种方法我们只需要挨个搜索下去,并每次判断棋盘是否翻完,再与之比较,取小值即可。
题解
1 #include<bits/stdc++.h>
2 using namespace std;
3 bool mp[6][6];
4 int ans=99999;//记最小步数
5 bool check()//判断16颗棋子是否都一样
6 {
7 for(int i=1;i<=4;i++)
8 {
9 for(int j=1;j<=4;j++)
10 if(mp[1][1]!=mp[i][j])return false;
11 }
12 return true;
13 }
14 void fan(int x,int y)//翻转它及周围的棋子
15 {
16 mp[x][y]=!mp[x][y];
17 mp[x+1][y]=!mp[x+1][y];
18 mp[x-1][y]=!mp[x-1][y];
19 mp[x][y+1]=!mp[x][y+1];
20 mp[x][y-1]=!mp[x][y-1];
21 }
22 void dfs(int num,int x,int y)
23 {
24 if(check())//如果找到方法
25 {
26 ans=min(ans,num);//取小值
27 return;
28 }
29 if(x==5)return;//一张图搜完了就没有了
30 //棋子不翻转时
31 if(y==4)dfs(num,x+1,1);//一排的最后一个,应当换行
32 else dfs(num,x,y+1);//否则继续向右
33 //棋子翻转时
34 fan(x,y);
35 if(y==4)dfs(num+1,x+1,1);//换行判断
36 else dfs(num+1,x,y+1);
37 fan(x,y);//取消标记,回溯操作
38 }
39 int main()
40 {
41 for(int i=1;i<=4;i++)
42 {
43 for(int j=1;j<=4;j++)
44 {
45 char a;//初始化存01矩阵
46 cin>>a;
47 if(a=='b')mp[i][j]=true;
48 else mp[i][j]=false;
49 }
50
51 }
52 dfs(0,1,1);
53 if(ans!=99999)cout<<ans;//ans值没变证明没找到方案
54 else cout<<"Impossible";
55 return 0;
56 }