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;
}
posted @ 2025-11-09 09:52  sxr1023  阅读(3)  评论(0)    收藏  举报