思路

这个题感觉只能枚举所有的翻转模式

但是这样明显会超时, 有

然后想了想,其实可以只枚举第一行的所有状态

然后找到一个不会影响前面行的翻转模式, 记录最少的翻转次数即可

N * M = 100 * 10 , 刚好 时间复杂度

翻转模式 : 对于上一行, 没有到位的棋子 , 逐个翻转下一行 , 最后再检查最后一行是不是就位即可

    auto get = [&](int st, int v)
    {
        int cnt = 0;
        b = a;
        for (int i = 0; i < m; i++)
        {
            if (st & (1 << i)) // 从第1行开始翻转
            {
                cnt++; // 翻转第i位
                // debug(b);
                change(1, i);
            }
        }

        for (int c = 2; c <= n; c++)
        {
            for (int r = 1; r <= m; r++)
            {
                if (b[c - 1][r] != v)
                {
                    cnt++;
                    change(c, r);
                }
            }
        }

        for (int i = 1; i <= m; i++)
            if (b[n][i] != v)
                return inf;

        return cnt;
    };

60% 代码 实在没看出来哪里错了

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
// const int inf = INT_MAX;
typedef pair<int, int> pii;
typedef priority_queue<int, vector<int>, greater<int>> small_heap;
#define int long long
const int inf = 0x3f3f3f3f;
int n, m;
void debug(vector<vector<bool>> &s)
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cout << s[i][j] << " ";
        }
        cout << endl;
    }
}
int32_t main()
{

    cin >> n >> m;
    vector<vector<bool>> a(n + 1, vector<bool>(m + 1, 0));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            char ch;
            cin >> ch;
            a[i][j] = ch - '0';
        }
    // debug(a);
    auto b = a;
    auto change = [&](int x, int y)
    {
        int dx[] = {0, 0, 1, -1, 0};
        int dy[] = {0, 1, 0, 0, -1};

        for (int i = 0; i < 5; i++)
        {
            int xx = dx[i] + x, yy = dy[i] + y;
            if (1 <= xx && xx <= n && 1 <= yy && yy <= m)
                b[xx][yy] = !b[xx][yy];
        }
    };
    auto get = [&](int st, int v)
    {
        int cnt = 0;
        b = a;
        for (int i = 0; i < m; i++)
        {
            if (st & (1 << i)) // 从第1行开始翻转
            {
                cnt++; // 翻转第i位
                // debug(b);
                change(1, i);
            }
        }

        for (int c = 2; c <= n; c++)
        {
            for (int r = 1; r <= m; r++)
            {
                if (b[c - 1][r] != v)
                {
                    cnt++;
                    change(c, r);
                }
            }
        }

        for (int i = 1; i <= m; i++)
            if (b[n][i] != v)
                return inf;

        return cnt;
    };
    int ans = inf + 1;
    for (int i = 0; i < (1 << m); i++)
    {
        ans = min(ans, get(i, 0));
        ans = min(ans, get(i, 1));
    }
    if (ans == inf)
        cout << "Impossible";
    else
        cout << ans;
    return 0;
}