hdu6171 双向bfs

hdu6171 Admiral
传送门

题意

有一个(6)行的舰队,第(i(1leq ileq 6))行有(i)艘战舰,共有(21)艘战舰,其中编号为(i(0leq ileq 5))的战舰有((i+1))艘,编号为(0)的那艘战舰上有司令,这艘战舰可以和周围四个方位的战舰交换位置:左上,上,下,右下。舰队的终态为编号为(i(0leq ileq 5))的战舰全部在第((i+1))行,给出始态,计算从初态到终态的最短步数,如果步数超过(20),输出"too difficult"。

题解

已知始态和终态,使用双向(bfs),队列中到达状态所需的步数不超过(10)步,状态通过(map)进行哈希映射成(LL)

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

//四个方向:左上,上,下,右下
int T,dir[4][2]={{-1,-1},{-1,0},{1,0},{1,1}};

struct node{
    int x,y;
    //flag==0表示正向,flag==1表示反向
    int state[6][6],flag,step;
};

map<LL,int> mp[2];
queue<node> q;

LL Hash(node a){
    LL ans=0;
    for(int i=0;i<6;i++){
        for(int j=0;j<=i;j++){
            ans=ans*6+a.state[i][j];
        }
    }
    return ans;
}

void bfs(){
    while(!q.empty()){
        node a=q.front();
        q.pop();
        if(mp[!a.flag].count(Hash(a))){
            printf("%d
",mp[!a.flag][Hash(a)]+a.step);
            return;
        }
        for(int k=0;k<4;k++){
            node b=a;
            int tx=b.x+dir[k][0];
            int ty=b.y+dir[k][1];
            if(tx<0 || tx>5 || ty<0 || ty>tx) continue;
            swap(b.state[b.x][b.y],b.state[tx][ty]);
            b.x=tx;
            b.y=ty;
            b.step++;
            if(b.step>10) continue;
            if(mp[b.flag].count(Hash(b))) continue;
            mp[b.flag][Hash(b)]=b.step;
            q.push(b);
        }
    }
    printf("too difficult
");
}

int main(){
    scanf("%d",&T);
    while(T--){
        node a,b;
        for(int i=0;i<6;i++){
            for(int j=0;j<=i;j++){
                scanf("%d",&a.state[i][j]);
                if(a.state[i][j]==0){
                    a.x=i;
                    a.y=j;
                }
                b.state[i][j]=i;
            }
        }
        a.flag=a.step=0;
        b.x=b.y=b.step=0;
        b.flag=1;
        mp[0].clear();
        mp[1].clear();
        while(!q.empty()) q.pop();
        q.push(a);
        q.push(b);
        mp[0][Hash(a)]=mp[1][Hash(b)]=0;
        bfs();
    }
}
原文地址:https://www.cnblogs.com/fxq1304/p/14528842.html