每次改变相邻位置,求最少步数到全部一样。这种矩阵求最少步数到某一状态一般是考虑BFS了,然后就是怎么简化题目的问题,反正就w和b这2个状态,0和1也是2个状态,所以很容易想到了位运算,16个位置看成16个2进制位就好(目的就是全1或全0),题目要求相邻位置改变,最近看MFC的我马上想到了逻辑操作符...这里的情况是反转,所以用异或...所以算法就很容易了,提前打表求出每一位相邻位置改变后的值(把该位置连同相邻置1,其余位置置0),然后BFS就行了
#include<stdio.h>
#include<string.h>
char str[10][10];
#define N 100000
int vis[N];
int d[16] = {
51200, 58368, 29184, 12544,
35968, 20032, 10016, 4880,
2248, 1252, 626, 305,
140, 78, 39, 19};
struct node
{
int num;
int step;
}p[N*4];
int bfs(int sum)
{
int head=0,tail=0,x,i;
p[head].num=sum;
vis[sum]=1;
tail++;
while(head<tail)
{//printf("123\n");
int k=p[head].num;
if(k==0x0000||k==0xffff)return p[head].step;
for(i=0;i<16;i++)
{
x=k^d[i];
if(!vis[x])
{
vis[x]=1;
if(x==0x0000||x==0xffff)return p[head].step+1;
p[tail].num=x;
p[tail].step=p[head].step+1;
tail++;
}
}
head++;
}
return 0;
}
int main()
{
int i,j;
memset(vis,0,sizeof(vis));
for(i=0;i<4;i++)
{
scanf("%s",str[i]);
}
int sum=0;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(str[i][j]=='b')
{
sum=sum<<1;
sum+=1;
}
else
{
sum=sum<<1;
}
}
}
if(sum==0x0000||sum==0xffff)
{
printf("0\n");
return 0;
}
int ans=bfs(sum);
if(ans)printf("%d\n",ans);
else printf("Impossible\n");