hdu 1401 (双广)

来源:互联网 发布:java图形界面的布局 编辑:程序博客网 时间:2024/04/30 21:20

      题意: 在一个8*8的棋盘里有4个棋子,给你这4个棋子的初状态和末状态,问你能否在8步内由初状态转换到末状态,每一步可移动一个棋子到(上下左右)相邻的空格子里,若相邻格子已有棋子,可跳过该棋子,但只可跳过一个棋子,若跳过后仍有棋子,则该方向不可走。

     分析:红果果的搜索题,但别看只走8步感觉状态挺少的,细算一下有(4*4)^8=2^32个状态!!再加上初,末状态已知,因此用双向广搜效率要高些,可把状态减少到2*(4*4)^4=2^17,减少的可不是一点半点。

      双向广搜是指从头,尾开始搜索,若搜索的过程中两者出现了交叉,则说明能实现状态转换。这里为了方便,我先搜索从起点出发的4步,并将搜索结果标记起来,再从终点开始搜索,若发现前面标记过了的状态,则说明状态可达。

      对于状态的储存用了二进制压缩,由于坐标都是从0到7,用三位二进制位就可以表示,8个坐标则总共是24个二进制位,一个int型就可以储存一个状态了。

    最后还有注意的一点是,在储存状态时一定要先对坐标排序,以免出现重复,比如 (2,3),(2,4),(5,6),(5,7)与(2,4),(5,6),(5,7),(2,3)虽然顺序不同,但都是同一个状态。

    代码:

#include<cstdio>#include<cstring>#include<iostream>#include<cstdlib>#include<cmath>#include<algorithm>#include<queue>#include<stack>#include<set>#include<map>using namespace std;const int N=10;int dx[4]={0,0,1,-1};int dy[4]={1,-1,0,0};map<int,int> m;struct node{    int x,y;    bool check()    {        if (x>=0 && x<8 && y>=0 && y<8) return true;        else return false;    }};typedef struct State{    node pos[4];    int step;}state;bool cmp(node a,node b){    return a.x!=b.x?a.x<b.x:a.y<b.y;}int set_hash(node *a){    int t=0;    sort(a,a+4,cmp);    for (int i=0;i<4;i++) {        t|=(a[i].x<<(6*i));        t|=(a[i].y<<(6*i+3));    }    return t; //printf("%o\n",t);}bool judge(int x,int y,node *a,int v){    for (int k=0;k<4;k++) if (k!=v) {        if (a[k].x==x && a[k].y==y) return false;    }    return true;}bool bfs(int kind,state a){    int i,j;    int t=set_hash(a.pos);    if (kind==2){        if (m[t]==1) return true;    }    m[t]=kind;    queue<state> q;    q.push(a);    while(!q.empty())    {        state u=q.front(); q.pop();        if (u.step>=4) continue;        for (i=0;i<4;i++)            for (j=0;j<4;j++)            {                state v=u; v.step++;                v.pos[i].x+=dx[j];                v.pos[i].y+=dy[j];                if (!v.pos[i].check()) continue;                if (judge(v.pos[i].x, v.pos[i].y, u.pos, i)){                    t=set_hash(v.pos);                    if (kind==1) {                        if (m[t]!=1) {  m[t]=1; q.push(v); }                    } else {                        if (m[t]==1) return true;                        else if (m[t]!=2) { m[t]=2; q.push(v); }                    }                } else {                    v.pos[i].x+=dx[j];                    v.pos[i].y+=dy[j];                    if (!v.pos[i].check() || !judge(v.pos[i].x, v.pos[i].y, u.pos, i)) continue;                    t=set_hash(v.pos);                    if (kind==1) {                        if (m[t]!=1) {  m[t]=1; q.push(v); }                    } else {                        if (m[t]==1) return true;                        else if (m[t]!=2) { m[t]=2; q.push(v); }                    }                }            }    }    return false;}int main(){    int i,j,k;    state s,e;    while(cin>>s.pos[0].x>>s.pos[0].y)    {        s.pos[0].x--; s.pos[0].y--;        for (i=1;i<4;i++){ cin>>s.pos[i].x>>s.pos[i].y; s.pos[i].x--; s.pos[i].y--; }        for (i=0;i<4;i++){ cin>>e.pos[i].x>>e.pos[i].y; e.pos[i].x--; e.pos[i].y--; }        s.step=0; e.step=0;        bfs(1,s);        printf("%s\n",bfs(2,e)?"YES":"NO");        m.clear();    }}



0 0
原创粉丝点击