zoukankan      html  css  js  c++  java
  • 胜利大逃亡(续)(bfs+状态压缩)

    胜利大逃亡(续)

    Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 85 Accepted Submission(s): 55
     
    Problem Description
    Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……

    这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。
     
    Input
    每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t>0)。接下来的n行m列为地牢的地图,其中包括:

    . 代表路
    * 代表墙
    @ 代表Ignatius的起始位置
    ^ 代表地牢的出口
    A-J 代表带锁的门,对应的钥匙分别为a-j
    a-j 代表钥匙,对应的门分别为A-J

    每组测试数据之间有一个空行。
     
    Output
    针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。
     
    Sample Input
    4 5 17
    @A.B.
    a*.*.
    *..*^
    c..b*
    
    4 5 16
    @A.B.
    a*.*.
    *..*^
    c..b*
     
    Sample Output
    16
    -1
     
    Author
    LL
     
    Source
    ACM暑期集训队练习赛(三)
     
    Recommend
    linle
     
    /*
    题意:略
    
    初步思路:这个题想了很久,钥匙的问题的没有办法解决,看了一下题解,才知道,搜索的状态在加一维就是压缩后的钥匙的状态,
        因为钥匙的数量不是很多,所以可以状态压缩一下来表示。
    */
    #include<bits/stdc++.h>
    using namespace std;
    int dir[4][2]={1,0,-1,0,0,1,0,-1};
    bool vis[22][22][(1<<11)];//用来标记走到i,j这个并且钥匙压缩完之后的状态是k的状态
    char mapn[22][22];//地图
    int sx,sy;//初始位置
    int n,m,t;
    struct node{
        int x,y,step,state;
        node(){}
        node(int a,int b,int c,int d){
            x=a;
            y=b;
            step=c;
            state=d;
        }
    };
    bool ok(int x,int y){//坐标状态是不是合法
        if(x<0||x>=n||y<0||y>=m||mapn[x][y]=='*') return false;
        return true;
    }
    bool judge(int x,int y,int state){//判断一下这种状态是不是能通过这扇门
        int res=mapn[x][y]-'A';
        if(((1<<res)&state)==0) return false;
        return true;
    }
    int bfs(){
        memset(vis,0,sizeof vis);
        node Next,start;
        queue<node>q;
        q.push(node(sx,sy,0,0));
        vis[sx][sy][0]=1;
        while(!q.empty()){
            start=q.front();
            q.pop();
            // cout<<start.x<<" "<<start.y<<" "<<start.state<<endl;
            if(start.step>=t){
                return -1;
            }
            if(mapn[start.x][start.y]=='^'){
                return start.step;
            }
            for(int i=0;i<4;i++){
                Next=start;
                Next.x+=dir[i][0];
                Next.y+=dir[i][1];
                Next.step++;//走了一步了
                if(ok(Next.x,Next.y)==false)//出界了
                    continue;
                if(mapn[Next.x][Next.y]>='A'&&mapn[Next.x][Next.y]<='Z'&&judge(Next.x,Next.y,Next.state)==false){//遇到门没有钥匙
                    // cout<<Next.x<<" "<<Next.y<<" "<<Next.state<<endl;
                    continue;
                }
                if(mapn[Next.x][Next.y]>='a'&&mapn[Next.x][Next.y]<='z'){//遇到钥匙
                    int res=mapn[Next.x][Next.y]-'a';
                    // cout<<"钥   匙="<<res<<endl;
                    // cout<<"状   态="<<Next.state<<endl;
                    Next.state=((1<<res)|Next.state);
                    // cout<<"事后状态="<<Next.state<<endl;
                }
                if(vis[Next.x][Next.y][Next.state]==1)//这个状态走过了
                    continue;
                vis[Next.x][Next.y][Next.state]=1;
                q.push(Next);
            }
        }    
        return -1;
    }
    int main(){
        // freopen("in.txt","r",stdin);
        while(scanf("%d%d%d",&n,&m,&t)!=EOF){
            for(int i=0;i<n;i++){
                scanf("%s",&mapn[i]);
                for(int j=0;j<m;j++){
                    if(mapn[i][j]=='@')
                        sx=i,sy=j;
                }
            }
            printf("%d
    ",bfs());
        }
        return 0;
    }
  • 相关阅读:
    vscode clang-format
    MyBatis中比较(大于、小于)符号的转义写法
    byte数组(byte[])与MultipartFile相互转化
    IDEA报错 Error:(24, 35) java: 常量字符串过长
    Nginx中配置反向代理的proxy_pass的不同斜杠的区别
    使用docker-compose一起安装kafka(zookeeper)
    docker启动报错:Failed to Setup IP tables: Unable to enable SKIP DNAT rule
    Xftp设置指定记事本(notepad++)打开文件
    Linux使用docker安装Nginx
    使用openssl生成证书,并通过Nginx配置
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6428428.html
Copyright © 2011-2022 走看看