题目描述
有n×n的正方形棋盘,每个格子里的棋子要么是黑色向上,要么是白色向上,当把一个格子里的棋子颜色改变(黑→白或者白→黑)时,其周围上下左右(如果存在的话)的格子里的棋子颜色也被反转!
问至少反转几个棋子可以使棋盘上的全部棋子变为白色或者黑色向上?
输入
输入第一行为一个整数n(1≤n≤16),随后n行n列描述棋盘,其中b代表黑色,w代表白色。
输出
输出一个整数即翻转次数。若无法完成,则输出“Impossible”。
AC代码:
#include <iostream>
using namespace std;
int map[20][20];
const int inf = 0x7fffffff;
int n,ans = inf;
void fz(int x,int y){
map[x - 1][y] ^= 1;
map[x][y - 1] ^= 1;
map[x][y] ^= 1;
map[x][y + 1] ^= 1;
map[x + 1][y] ^= 1;
}
void dfs(int row,int step,int value)
{
if(row == n + 1)
{
for(int i = 1;i <= n;i ++){
if(map[n][i] == value)
return;
}
ans = min(step,ans);
return;
}
int v = 0;
for(int i = 1;i <= n;i ++){
if(map[row - 1][i] == value){
step++;
fz(row,i);
v = v | (1 << (i - 1));
}
}
dfs(row + 1,step,value);
for(int i = 1;i <= n;i ++){
if((v >> (i - 1)) & 1)
fz(row,i);
}
}
int main()
{
cin >> n;
char ch;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= n;j ++){
cin >> ch;
map[i][j] = (ch == 'b');
}
}
for(int k = 0;k < (1 << n);k ++)
{
for(int i = 1;i <= n;i ++){
map[0][i] = (k >> (i - 1)) & 1;
}
dfs(1,0,0);
dfs(1,0,1);
}
if(ans != inf) cout << ans << endl;
else cout << "Impossible" << endl;
return 0;
}
运行结果

文章讨论了一个问题,给定一个n×n的棋盘,棋子按黑白交替排列,通过最少的棋子颜色反转操作,使得所有棋子颜色一致。使用深度优先搜索策略和编程实现解决此问题。

1469

被折叠的 条评论
为什么被折叠?



