zoukankan      html  css  js  c++  java
  • hdu 5094 Maze (BFS+状压)

    题意:

    n*m的迷宫。多多要从(1,1)到达(n,m)。每移动一步消耗1秒。有P种钥匙。

    有K个门或墙。给出K个信息:x1,y1,x2,y2,gi    含义是(x1,y1)与(x2,y2)之间有gi。gi=0:墙   1,2,3.... :第1种门,第2种门,第3种门.....

    有S把钥匙。给出S个信息:x1,y1,qi    含义是位置(x1,y1)上有一把第qi种的钥匙。

    问多多最少花多少秒到达(n,m)。若无法到达输出-1。

    数据范围:

    (1<= n, m <=50, 0<= p <=10).

    (0<= k <=500)

    (0<= S <=50)

    思路:

    n,m很小。经典BFS+状压,

    注意的是,同一位置上可能有多把钥匙。(注意到S的范围是S<=50)

    还有一个要注意:位运算式子的处理要仔细。(最好测试一下)。

    代码:

    struct node{
        int x,s;
        node(int _x,int _s){
            x=_x, s=_s;
        }
    };
    
    int n,m,p,k,S;
    int xx1,yy1,xx2,yy2,gi;
    int mazeG[55][55][55][55], mazeK[55][55][15];
    int dp[55][55][1050];
    
    
    
    int bfs(){
        queue<node> q;
        mem(dp,-1);
        int s=0;
        rep(i,1,p) if(mazeK[1][1][i]>0) s|=(1<<(i-1));
        q.push(node(101,s));
        dp[1][1][s]=0;
        if(1==n && 1==m) return 0;
        while(!q.empty()){
            node f=q.front();  q.pop();
            rep(i,0,3){
                int nx=f.x/100+uu[i], ny=f.x%100+vv[i];
                int _s=f.s;
                if(nx<=0||ny<=0||nx>n||ny>m||(mazeG[f.x/100][f.x%100][nx][ny]==0)) continue; //overBound or meet the wall.
    
                if(mazeG[f.x/100][f.x%100][nx][ny]>0){
                    int yes=_s&(1<<(mazeG[f.x/100][f.x%100][nx][ny]-1));
                    if(yes==0) continue; //don't have corresponding key.
                }
                int ns=_s;
                rep(i,1,p) if(mazeK[nx][ny][i]) ns|=(1<<(i-1));
                if(dp[nx][ny][ns]!=-1) continue;
                q.push(node(nx*100+ny,ns));
                dp[nx][ny][ns]=dp[f.x/100][f.x%100][_s]+1;
                if(nx==n&&ny==m) return dp[nx][ny][ns];
            }
        }
        return -1;
    }
    
    
    int main(){
        while(scanf("%d%d%d",&n,&m,&p)!=EOF){ //p kinds of doors
            scanf("%d",&k);
            mem(mazeG,-1); //doors or walls
            mem(mazeK,false); //keys
            rep(i,1,k){
                scanf("%d%d%d%d%d",&xx1,&yy1,&xx2,&yy2,&gi);
                mazeG[xx1][yy1][xx2][yy2]=gi;
                mazeG[xx2][yy2][xx1][yy1]=gi;
            }
            scanf("%d",&S); // S keys
            rep(i,1,S){
                scanf("%d%d%d",&xx1,&yy1,&gi);
                mazeK[xx1][yy1][gi]=true;
            }
            printf("%d
    ",bfs());
        }
    }
  • 相关阅读:
    uniApp 实现微信小程序和app视频播放flv格式视频监控
    uniapp 给子组件传值不及时显示
    uni-app 中$refs 在app中无法使用
    使用甘特图
    背景图片加蒙版,里面内容不受影响
    MyBatis 多对一操作
    在Maven项目中使用lombok
    MyBatis使用分页
    Log4j打印日志
    paramiko 下载文件
  • 原文地址:https://www.cnblogs.com/fish7/p/4085896.html
Copyright © 2011-2022 走看看