題意:一個4*4的棋盤,每個格子上有一個黑白棋(黑色朝上或白色朝上),定義操作翻轉某個位置的棋子,同時也翻轉其上下左右四個棋子,求把整個棋盤翻轉成都是白色朝上或者黑色朝上的最少步數。
思路:對於某個位置的棋子,我們可以看出翻2次和不翻效果是一樣的,翻3次效果和翻1次效果一樣,所以對於每個位置只有兩種情況:翻1次或者不翻,同時翻的順序對結果也並沒有影響,由此,假設我們已經找到一種翻第一行棋子的策略,那麼要滿足最後是同種顏色朝上,那麼第二行的翻轉策略已經固定只有兩種(一種使第一行白色朝上,一種使第一行黑色朝上),以此類推,所以我們只要枚舉第一行的翻轉策略就行了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<deque>
#define ll long long
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 500020
#define debug true
#define lowbit(x) ((-x)&x)
#define ffor(i,d,u) for(int i=(d);i<=(u);++i)
#define _ffor(i,u,d) for(int i=(u);i>=(d);--i)
#define mst(array,Num,Kind,Count) memset(array,Num,sizeof(Kind)*(Count))
using std::min;
const int P = 1e9+7;
bool ch[5][5],ch1[5][5];
int ans;
template <typename T>
void read(T& x)
{
x=0;
char c;T t=1;
while(((c=getchar())<'0'||c>'9')&&c!='-');
if(c=='-'){t=-1;c=getchar();}
do(x*=10)+=(c-'0');while((c=getchar())>='0'&&c<='9');
x*=t;
}
template <typename T>
void write(T x)
{
int len=0;char c[21];
if(x<0)putchar('-'),x*=(-1);
do{++len;c[len]=(x%10)+'0';}while(x/=10);
_ffor(i,len,1)putchar(c[i]);
}
inline void turn(bool &x)
{
x = !x;
}
inline bool check(bool flag)
{
ffor(i,1,4)if(ch[4][i] != flag)return false;
return true;
}
int tryy(int line,bool flag,int step)
{
if(line == 5)return (check(flag)?step:INF);
ffor(i,1,4)
if(ch[line-1][i] != flag)
{
ch[line-1][i] = flag;
if(i > 1)turn(ch[line][i-1]);
turn(ch[line][i]);
if(i < 4)turn(ch[line][i+1]);
if(line < 4)turn(ch[line+1][i]);
++step;
}
return tryy(line+1,flag,step);
}
int solve(bool flag)
{
int ans = INF,step,x;
int a[5];
ffor(i,0,15)
{
x = i;
ffor(j,1,4)ch[1][j] = ch1[1][j],a[j] = x%2,x /= 2;
ffor(i,2,4)ffor(j,1,4)ch[i][j] = ch1[i][j];
step = 0;
ffor(j,1,4)
{
if(a[j] == 0)continue;
turn(ch[1][j]);
if(j > 1)turn(ch[1][j-1]);
if(j < 4)turn(ch[1][j+1]);
turn(ch[2][j]);
++step;
}
x = tryy(2,flag,step);
ans = min(ans,x);
}
return ans;
}
inline void AC()
{
char x;
ffor(i,1,4)
{
ffor(j,1,4)x = getchar(),ch1[i][j] = (x == 'b');
getchar();
}
ans = solve(false);
ans = min(ans,solve(true));
if(ans == INF)puts("Impossible");
else write(ans),putchar('\n');
}
int main()
{
AC();
return 0;
}