poj 1753 bfs+位运算

接上一篇本题dfs
耗时2天写出来的第一个位运算。
唯一记住一件事:网上推荐poj刷题水题请千万不要相信它水。
传送poj 1753

因为每个棋子只有黑白2种颜色可以用0,1两个数字来表示,这样用16个0或者1,就可以表示出来当前期盼的状态。然后使用异或操作将需要翻的棋子翻过来。

推荐一篇博客哦,讲的很详细,而且写的不太一样

直接上代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
bool vis[65535]={0};
int step[65535]; 
int k;
int x;//存储棋盘当前状态 
queue<int> q;

int flip(int x,int pos)//当前棋盘为x状态时,翻第i个棋子 ,感谢题解大大和Sirius同学 w 
{
    x=x^(1<<pos);   //翻pos上的棋子 
    if(pos%4!=0) x=x^(1<<(pos-1));//左 
    if(pos>=4) x=x^(1<<(pos-4));  //上 
    if(pos%4!=3) x=x^(1<<(pos+1)); //右
    if(pos<12) x=x^(1<<(pos+4));//下 
    return x;
}
int bfs(int x)
{
    memset(vis,0,sizeof(vis));   //visit数组记录有无被翻 
    step[x]=0;
    q.push(x);
    vis[x]=1;
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i = 0; i < 16; i++)  //遍历每一个点 
        {
            int next=flip(now,i);//翻转当前情况 
            if(vis[next]!=0)   //这个点被翻过了,翻下一个点 
            {
                continue;
            } 
            step[next]=step[now]+1; 
            if(next == 0 || next == 65535)  //达到目标状态 
            {
                return step[next];
            }   
            vis[next]=1;           //这个点被翻过啦 
            q.push(next);  //当前状态载入队列 
        } 
    }
    return -999;           //搜完所有也达不到 
}

int main()
{
    char chess[10];
    x=0;
    for(int i=0;i<4;i++) //输入陷害朕啊!!!一开始就输错了,找了个题解对照一下输入。。汗 
    {
        scanf("%s",chess);  //输入4行 
        //printf("%s",chess);
        for(int j=0;j<4;j++,k++)
        {
            if(chess[j] == 'b')
            {
                x+=1<<k;
            }
            else
            {
                x+=0<<k;
            }
        }
    }
    //printf("%d\n",x); 
        if( x == 0|| x == 65535)
        {
            cout<<'0'<<endl;
        }
        else
        {
        int ans=bfs(x);
        if(ans == -999)
        {
            cout<<"Impossible"<<endl;
        }
        else
        {
            cout<<ans<<endl;
        }   
        }

}

朕心情愉悦【笑
然后周一月考呵呵呵。
再然后 a better tomorrow
nighty

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值