zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    
  • 相关阅读:
    linux/eclipse/c++ 动态库的创立与调用
    虚拟机NetworkAdapter三种方式的区别
    关于“三层架构”和MVC
    C# 扩展方法
    鼠标拖移对象
    获取应用程序根目录物理路径(Web and Windows)
    一个简单的管理Web站点文件的页面程序(修改版)
    一个基于jQuery的简单树形菜单
    以人为本的程序的设计
    一个加密解密的小工具及源码(MD5, DES, RSA)
  • 原文地址:https://www.cnblogs.com/fxq1304/p/14528842.html
Copyright © 2011-2022 走看看