7段第一课:枚举
A 按钮变色
题目&解法
题目:有一个 \(4\times4\) 的网格上面有 \(16\) 个按钮。按钮只有黑 (\(b\))白 (\(w\)) 两种颜色。按动任意一个按钮,那么该按钮本身以及其上下左右的按钮(如果有的话)都会改变颜色(由白变黑,由黑变白)。给出初始按钮的状态,输出最少要按多少次按钮才可以让所有按钮变为同一种颜色。
解法:爆搜即可,每个按钮有按下与不按下两种可能。可以把每个按钮进行编号,第一行是 \(0\) 到 \(3\),第二行是 $4 $ 到 \(7\),以此类推,优点是方便 dfs 的时候枚举下一个
code
#include <bits/stdc++.h>
using namespace std;
char s[5][5];
int ans = 20;
char f(char c) {return c == 'w' ? 'b' : 'w';}
bool check() {
char op = s[0][0];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (s[i][j] != op) return false;
}
}
return true;
}
void change(int x, int y) {
s[x][y] = f(s[x][y]);
if (x - 1 >= 0) s[x - 1][y] = f(s[x - 1][y]);
if (x + 1 < 4) s[x + 1][y] = f(s[x + 1][y]);
if (y - 1 >= 0) s[x][y - 1] = f(s[x][y - 1]);
if (y + 1 < 4) s[x][y + 1] = f(s[x][y + 1]);
}
//id是当前的按钮编号,cnt是当前按下的按钮次数
void dfs(int id, int cnt) {
if (id == 16) {
if (check()) ans = min(ans, cnt);
return ;
}
int x = id / 4;
int y = id - x * 4;
dfs(id + 1, cnt);
change(x, y);
dfs(id + 1, cnt + 1);
change(x, y);
}
int main() {
for (int i = 0; i < 4; i++) {
scanf("%s", s[i]);
}
dfs(0, 0);
if (ans != 20) printf("%d\n", ans);
else printf("Impossible\n");
return 0;
}

浙公网安备 33010602011771号