题意:在一个棋盘上,每个格子摆放有一枚棋子,每一枚棋子的颜色要么是黑色,要么是白色。每次操作可以选择一枚棋子,将它的颜色翻转(黑变白,白变黑),同时将这枚棋子上下左右相邻的四枚棋子的颜色翻转(如果对应位置有棋子的话)。
判断能否通过多次操作将所有棋子都变成黑色或者白色?如果可以,最小操作次数又是多少呢?

思路:二进制枚举第一行的所有情况,不断通过上一行推断当前行的翻转状态。

本蒟蒻的第一篇题解,求大佬拷打" src="https://uploadfiles.nowcoder.com/images/20220815/318889480_1660553763930/8B36D115CE5468E380708713273FEF43" />" src="https://uploadfiles.nowcoder.com/images/20220815/318889480_1660553763930/8B36D115CE5468E380708713273FEF43" />" src="https://uploadfiles.nowcoder.com/images/20220815/318889480_1660553763930/8B36D115CE5468E380708713273FEF43" />
#include <bits/stdc++.h>
#define int long long
using namespace std;

int n, m;
int a[105][15], tt[105][15];

int f(int key) {
    int ans = INT_MAX;
    for (int i = 0; i < 1 << m; i++) {
        for (int j = 0; j < n; j++)
            for (int k = 0; k < m; k++)
                tt[j][k] = a[j][k];
        int res = 0;
        for (int j = 0; j < m; j++) {
            if ((i >> j) & 1) {
                tt[0][j] ^= 1;
                if (j != 0)
                    tt[0][j - 1] ^= 1;
                if (j != m - 1)
                    tt[0][j + 1] ^= 1;
                if (n != 1)
                    tt[1][j] ^= 1;
                res++;
            }
        }
        for (int j = 1; j < n; j++) {
            for (int k = 0; k < m; k++) {
                if (tt[j - 1][k] != key) {
                    res++;
                    tt[j - 1][k] ^= 1;
                    tt[j][k] ^= 1;
                    if (j != n - 1)
                        tt[j + 1][k] ^= 1;
                    if (k != 0)
                        tt[j][k - 1] ^= 1;
                    if (k != m - 1)
                        tt[j][k + 1] ^= 1;
                }
            }
        }
        bool flag = 1;
        for (int j = 0; j < m; j++) {
            if (tt[n - 1][j] != key) {
                flag = 0;
                break;
            }
        }
        if (flag)
            ans = min(res, ans);
    }
    return ans;
}

void solve() {
    cin >> n >> m;
    char ch;
    for (int i = 0; i < n; i++){
        for (int j = 0; j < m; j++){
            //注意题目中的输入格式是一连串数字,不能直接cin>>a[i][j]
            cin>>ch;
            a[i][j]=ch-'0';
        }
    }
    int ans = min(f(1), f(0));
    if (ans == INT_MAX)
        cout << "Impossible" << endl;
    else
        cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    int t = 1;
    // cin>>t;
    while (t--)
        solve();
    return 0;
}