这个题大意是说你可以任意翻转一个点,然后它所在的上下左右(如果存在)也会跟着翻转,问将其翻转成全部一致最少需要多少次。
用BFS搜索做吧。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<string>
const int MAX=(1<<16)+1;
const int res=(1<<16)-1;
using namespace std;
bool vis[MAX];
struct node
{
int num;
int ans;
};
int main()
{
char str[4][4];
while(scanf("%s",&str[0])!=EOF)
{
for(int i=1;i<4;i++)
scanf("%s",str[i]);
memset(vis,0,sizeof(vis));
node ita;
ita.num=0;
ita.ans=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(str[i][j]=='w')
ita.num+=(1<<(i*4+j));
if(ita.num==res||ita.num==0)
{
printf("0\n");
continue;
}
queue<node> q;
q.push(ita);
vis[ita.num]=1;
int ans=-1;
while(!q.empty())
{
ita=q.front();
q.pop();
for(int i=0;i<16;i++)
{
node itb=ita;
itb.num=(itb.num^(1<<i));
if(i>=4)
itb.num=(itb.num^(1<<(i-4)));
if(i<12)
itb.num=(itb.num^(1<<(i+4)));
if(i%4!=0)
itb.num=(itb.num^(1<<i-1));
if((i+1)%4!=0)
itb.num=(itb.num^(1<<i+1));
if(vis[itb.num])
continue;
if(itb.num==0||itb.num==res)
{
ans=ita.ans+1;
break;
}
itb.ans=ita.ans+1;
q.push(itb);
vis[itb.num]=1;
}
if(ans!=-1)
{
while(!q.empty())
q.pop();
break;
}
}
if(ans==-1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}