毫无疑问,这道题需要枚举。并且,如果其他三行(三列)都已如题所述的弄好,那么,最后一行(一列)如果还不好,就无解。从上往下一行一行的看,假如第一行没有全白(全黑),那么可以通过第二行的翻转来改变第一行使其全白(全黑),第三行同理,只有第四行剩下,所以,可以通过检测第四行是否全白(全黑)来检验这种翻转方法是否可行。同时,正因此,第一行如何翻转决定了以后的走向。所以,可以通过01串(转化成十进制数字更好一点)来枚举表达第一行的翻转情况,之后的行通过弥补之前行的差错来进行翻转。这样就大功告成了!对了,别忘了有全白全黑两种情况的。
剩下的部分可以看代码注释

#include <iostream>
#include <algorithm>

using namespace std;
char ch[4][4];   //接受到的字符
bool th_b[4][4]; //用01表示黑白两种状态, 这个表示全黑
bool th_w[4][4]; //这个表示全白

void flip(bool(*th)[4], int row, int col) //反转黑白
{
    th[row][col] = !th[row][col];
}

void read(char(*a)[4], bool(*b)[4], bool(*c)[4])  //读入字符,转化成01
{
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            if (a[i][j] == 'w')
                b[i][j] = c[i][j] = 0;
            else
                b[i][j] = c[i][j] = 1;
        }
    }
}

int solve_b(bool(*th)[4])     全白情况
{
    int count = 0;
    for (int row = 1; row < 4; ++row)
    {
        for (int col = 0; col < 4; ++col)
        {
            if (!th[row - 1][col]) //0表示白
            {
                ++count;
                flip(th, row, col);
                flip(th, row - 1, col);
                if (row + 1 <= 3) //下边
                    flip(th, row + 1, col);
                if (col + 1 <= 3) //右边
                    flip(th, row, col + 1);
                if (col - 1 >= 0) //左边
                    flip(th, row, col - 1);
            }
        }
    }
    int ss = 0;
    for (int i = 0; i < 4; ++i)
        ss += th[3][i];
    if (ss == 4)
        return count;
    else
        return 0;
}

int solve_w(bool(*th)[4])   //全黑情况
{
    int count = 0;
    for (int row = 1; row < 4; ++row)
    {
        for (int col = 0; col < 4; ++col)
        {
            if (th[row - 1][col]) //1表示黑
            {
                ++count;
                flip(th, row, col);
                flip(th, row - 1, col);
                if (row + 1 <= 3)
                    flip(th, row + 1, col);
                if (col + 1 <= 3)
                    flip(th, row, col + 1);
                if (col - 1 >= 0)
                    flip(th, row, col - 1);
            }
        }
    }
    int ss = 0;
    for (int i = 0; i < 4; ++i)
        ss += th[3][i];
    if (ss == 0)
        return count;
    else
        return 0;
}

int toByte(bool (*th_b)[4], bool (*th_w)[4], int num)
{
    int _ans = 0;
    for (int i = 0; i < 4; ++i)
    {
        if ((num >> i) & 0x1) //对第一行的翻转
        {
            flip(th_b, 0, i);
            flip(th_b, 1, i);
            flip(th_w, 0, i);
            flip(th_w, 1, i);
            if (i + 1 < 4)
            {
                flip(th_w, 0, i + 1);
                flip(th_b, 0, i + 1);
            }
            if (i - 1 >= 0)
            {
                flip(th_w, 0, i - 1);
                flip(th_b, 0, i - 1);
            }
            ++_ans;
        }
    }
    return _ans;
}

int main(void)
{
    for (int i = 0; i < 4; ++i)
        cin >> ch[i];
    int ans = 0x7f7f7f7f, s(0);

    read(ch, th_w, th_b);
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            s += th_w[i][j];
    if (s == 0 || s == 16)   //特殊情况
    {
        cout << 0 << endl;
        return 0;
    }

    for (int i = 0; i < 16; ++i)
    {
        read(ch, th_w, th_b);
        int sum1 = toByte(th_w, th_b, i), sum = 0, b = 0x7f7f, a = 0x7f7f;
        int sum_w = solve_w(th_w);
        int sum_b = solve_b(th_b);
        if (sum_w)
            a = sum1 + sum_w;
        if (sum_b)
            b = sum1 + sum_b;
        if (a == 0x7f7f && b == 0x7f7f)
            continue;
        sum = min(a, b);
        ans = min(ans, sum);
    }
    if (ans < 0x7f7f7f7f)
        cout << ans << endl;
    else
        cout << "Impossible" << endl;
    return 0;
}

唉,这个题我之前在写第一行的时候忘了上下左右了,害的我迷茫了好久