洛谷 - P1225 - 黑白棋游戏 - bfs

神奇bug,没有记录pre就show了,找了1个小时。

#include <bits/stdc++.h>
using namespace std;
#define ll long long

int C=0;

int encode(int *a)
{
    int res=0;
    for(int i=0;i<16; i++)
    {
        if(a[i])
            res|=1;
        res<<=1;
    }
    return res>>1;
}

void decode(int code,int *a)
{
    for(int i=15; i>=0; i--)
    {
        a[i]=code&1;
        code>>=1;
    }
}


struct dat
{
    int cur;
    int pre;
} d,dt,data[65536];

queue<dat> q;

void showbit(int s){
    string str;
    for(int i=0;i<16;i++){
        str=char((s&1)+'0')+str;
        s>>=1;
        if(i%4==3)
            str='\n'+str;
    }
    cout<<str<<endl;
}

void show(dat d)
{
    //cout<<"show"<<endl;
    stack<int> s;
    s.push(d.cur);
    while(1)
    {
        if(d.pre==-1)
            break;
        s.push(d.pre);
        d=data[d.pre];
    }

    printf("%d",s.size()-1);

    int cur=s.top();

    while(!s.empty())
    {
        int nex=s.top();
        //showbit(cur);

        s.pop();

        for(int i=15;i>=0;i--){
            if(((cur>>i)&1)!=((nex>>i)&1)){
                //cout<<bitset<32>(cur)<<endl;
                //cout<<bitset<32>(nex)<<endl<<endl;
                int t=16-i;
                printf("%d%d",(t+3)/4,(t%4)==0?4:t%4);
            }
        }
        printf("\n");
        cur=nex;
    }

    //showbit(cur);
}

int t;

inline bool found(int code)
{
    return (code==t);
}

void bfs(int s)
{
    memset(data,-1,sizeof(data));

    d.cur=s;
    d.pre=-1;

    if(found(d.cur))
    {
        show(d);
        return;
    }

    data[d.cur]=d;
    q.push(d);

    while(!q.empty())
    {
        d=q.front();
        q.pop();

        //cout<<bitset<32>(d.cur)<<endl;

        for(int i=0;i<16;i++){
            for(int j=i+1;j<16;j++){
                if((abs(i-j)==4||((i/4==j/4)&&(abs(i-j)==1)))&&(((d.cur>>i)&1)!=((d.cur>>j)&1))){
                    //cout<<"i="<<i<<" j="<<j<<endl;
                    dt.cur=(d.cur^((1<<i)^(1<<j)));
                    /*if(bitset<32>(d.cur).count()!=8&&bitset<32>(dt.cur).count()!=8){
                        cout<<bitset<32>(d.cur)<<endl;
                        cout<<bitset<32>(dt.cur)<<endl;
                    }*/

                    if(data[dt.cur].cur==-1){
                        dt.pre=d.cur;
                        data[dt.cur]=dt;
                        q.push(dt);
                        if(found(dt.cur)){
                            show(dt);
                            return;
                        }
                    }
                }
            }
        }
    }
}

int main()
{
    int a[16];
    for(int i=0; i<16; i++)
    {
        scanf("%1d",&a[i]);
    }

    int s=encode(a);

    /*printf("s=%d\n",s);
    cout<<bitset<32>(s)<<endl;

    decode(s,a);
    for(int i=0; i<16; i++)
    {
        printf("%d%c",a[i]," \n"[i%4==3]);
    }*/


    for(int i=0; i<16; i++)
    {
        scanf("%1d",&a[i]);
    }
    t=encode(a);

    /*printf("t=%d\n",t);
    cout<<bitset<32>(t)<<endl;

    decode(t,a);
    for(int i=0; i<16; i++)
    {
        printf("%d%c",a[i]," \n"[i%4==3]);
    }*/

    bfs(s);
}

 

转载于:https://www.cnblogs.com/Yinku/p/10542354.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值