附原文:
http://blog.sina.com.cn/s/blog_6635898a0100ivzv.html
题意:一个4*4的矩阵,每一格要么是白色,要么是黑色。现在你可以选择任意一个格变成相反的颜色,则这个格的上,下,左,右四个格也会跟着变成相反的色(如果存在的话)。问要把矩阵的所有格子变成同一个颜色,你最少需执行几次上面的操作。
思路:枚举+dfs。一个关键点:对于每一格,只能翻0或1次(易证)。因此枚举就存在2^16 = 4096个状态,最多执行16次操作,因此可行。
#include<iostream>
using namespace std;
bool isgoal();
void flip(int row, int cow);
void dfs(int row, int cow, int ste);
int dr[5] = {-1, 0, 0, 0, 1};
int dc[5] = {0, -1, 0, 1, 0};
int step;
bool findd=false;
bool a[6][6];
int main(){
int i, j;
char c;
for(i = 1; i <= 4; i ++)
for(j = 1; j <= 4; j ++){
cin >> c;
if(c == 'b'){
a[i][j] = true;
}
}
for(step = 0; step <= 16; step ++){
dfs(1, 1, 0);
if(findd)
break;
}
if(findd) cout << step << endl;
else cout << "Impossible" << endl;
return(0);
}
void dfs(int row, int col, int ste){
if(ste == step){
findd = isgoal();
return;
}
if(row == 5 || findd) return;
flip(row, col);
if(col < 4) dfs(row, col + 1, ste + 1);
else dfs(row + 1, 1, ste + 1);
flip(row, col);
if(col < 4) dfs(row, col + 1, ste);
else dfs(row + 1, 1, ste);
return;
}
void flip(int row,int col){
int i, h, l;
for(i = 0; i < 5; i ++){
h = row + dr[i];
l = col + dc[i];
a[h][l] = !a[h][l];
}
return;
}
bool isgoal(){
int i,j;
for(i = 1; i <= 4; i ++)
for(j = 1; j <= 4; j ++)
if(a[i][j] != a[1][1])
return(false);
return(true);
}