poj 1753 Flip Game(枚举)

每次改变相邻位置,求最少步数到全部一样。这种矩阵求最少步数到某一状态一般是考虑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");

}

原文地址:https://www.cnblogs.com/acSzz/p/2361877.html