每个位置翻转2次相当于没翻,另外每个位置翻转的时机不影响最终结果,所以枚举每个位置的状态翻还是没翻,一共2^16次递归
#include<iostream>
#include <string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum = 10005;
int mat[4][4];
bool vis[4][4];
int nxt[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
void flip(int x,int y){
mat[x][y]=1-mat[x][y];
FOR(i,0,3){
if((x+nxt[i][0])>=0&&(x+nxt[i][0])<4&&(y+nxt[i][1])>=0&&(y+nxt[i][1])<4){
mat[x+nxt[i][0]][y+nxt[i][1]]=1-mat[x+nxt[i][0]][y+nxt[i][1]];
}
}
/*printf("\n");
FOR(i,0,3){
FOR(j,0,3){
printf("%d",mat[i][j]);
}
printf("\n");
}*/
}
bool check(){
int sum=0;
FOR(i,0,3){
FOR(j,0,3){
sum+=mat[i][j];
}
}
if (sum==0||sum==16)
{
return true;
}
return false;
}
int mintime=100;
void enumM(int n,int times){
if(n==16)return;
enumM(n+1,times);
flip(n/4,n%4);
if(check()){
mintime=min(mintime,times);
}
enumM(n+1,times+1);
flip(n/4,n%4);
}
int main()
{
char ch;
FOR(i,0,3){
FOR(j,0,3){
scanf("%c",&ch);
if(ch=='w')mat[i][j]=0;
else mat[i][j]=1;
}scanf("%c",&ch);
}
ms(vis);
if(check()) printf("0\n");
else{
enumM(0,1);
if(mintime>16)printf("Impossible\n");
else printf("%d\n",mintime);
}
}