HDU1401 Solitaire

题目描述:
8×8的棋盘上有4个棋子,棋子的运动方法如下:
1.如果其上/下/左/右一格没有棋子,则可以去;2.如果其上/下/左/右一格有棋子,而且沿原方向再跳一步没有,则可以去。

给出初始结束位置,问8步以内能否走到?

题解:
双向BFS。

从初始结束位置一起跑4步。

也称meet_in_the_middle

代码:

#include<map>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
bool ck(int x,int y){return x>=1&&x<=8&&y>=1&&y<=8;}
struct P
{
    int x,y;
    P(){}
    P(int x,int y):x(x),y(y){}
};
bool cmp(P a,P b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x<b.x;
}
struct sp
{
    P s[5];
    int v()
    {
        int hs = 0;
        for(int i=1;i<=4;i++)hs=hs*67+(s[i].x-1)*8+s[i].y-1;
        return hs;
    }
    bool emp(int x,int y)
    {
        if(!ck(x,y))return 0;
        for(int i=1;i<=4;i++)if(s[i].x==x&&s[i].y==y)return 0;
        return 1;
    }
    void bal()
    {
        sort(s+1,s+5,cmp);
    }
}a,b,u,t;
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int bfs()
{
    map<int,int>mp1,mp2;
    queue<sp>q1,q2,tmp;
    int hs1,hs2,x,y,tx,ty;
    hs1 = a.v(),hs2=b.v();
    if(hs1==hs2)return 1;
    mp1[hs1]=mp2[hs2]=1;
    q1.push(a),q2.push(b);
    for(register int dep=1;dep<=4;dep++)
    {
        while(!q1.empty())
        {
            u = q1.front();
            q1.pop();
            for(register int i=1;i<=4;i++)
            {
                x = u.s[i].x,y = u.s[i].y;
                for(register int j=0;j<4;j++)
                {
                    t=u;
                    tx=x+dx[j],ty=y+dy[j];
                    if(!t.emp(tx,ty))
                    {
                        tx+=dx[j],ty+=dy[j];
                    }
                    if(t.emp(tx,ty))
                    {
                        t.s[i].x=tx,t.s[i].y=ty;
                        t.bal();
                        hs1 = t.v();
                        if(mp2[hs1])return dep+mp2[hs1];
                        if(!mp1[hs1])
                        {
                            mp1[hs1]=dep;
                            tmp.push(t);
                        }
                    }
                }
            }
        }
        while(!tmp.empty())q1.push(tmp.front()),tmp.pop();
        while(!q2.empty())
        {
            u = q2.front();
            q2.pop();
            for(register int i=1;i<=4;i++)
            {
                x = u.s[i].x,y = u.s[i].y;
                for(register int j=0;j<4;j++)
                {
                    t=u;
                    tx=x+dx[j],ty=y+dy[j];
                    if(!t.emp(tx,ty))
                    {
                        tx+=dx[j],ty+=dy[j];
                    }
                    if(t.emp(tx,ty))
                    {
                        t.s[i].x=tx,t.s[i].y=ty;
                        t.bal();
                        hs2 = t.v();
                        if(mp1[hs2])return dep+mp1[hs2];
                        if(!mp2[hs2])
                        {
                            mp2[hs2]=dep;
                            tmp.push(t);
                        }
                    }
                }
            }
        }
        while(!tmp.empty())q2.push(tmp.front()),tmp.pop();
    }
    return 0;
}
int main()
{
    while(scanf("%d%d",&a.s[1].x,&a.s[1].y)>0)
    {
        for(int i=2;i<=4;i++)scanf("%d%d",&a.s[i].x,&a.s[i].y);
        for(int i=1;i<=4;i++)scanf("%d%d",&b.s[i].x,&b.s[i].y);
        sort(a.s+1,a.s+5,cmp),sort(b.s+1,b.s+5,cmp);
        printf(bfs()?"YES\n":"NO\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LiGuanlin1124/p/10002645.html