• 胜利大逃亡(hdu1429 bfs+状态压缩)


    胜利大逃亡(续)

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 12578    Accepted Submission(s): 4570


    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
     
    解题思路: 具体看代码
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <bitset>
     7 
     8 using namespace std;
     9 
    10 int n,m,step,start_x,start_y,end_x,end_y;
    11 int arr[25][25],vis[25][25][1<<11];
    12 int door[25][25],key[25][25];
    13 int fx[4][2]={1,0,-1,0,0,1,0,-1};
    14 string name;
    15 
    16 struct Node{
    17     int x,y,num,state;
    18 }p;
    19 
    20 queue<Node> que;
    21 
    22 void init(){
    23     memset(vis,0,sizeof(vis));
    24     memset(door,0,sizeof(door));
    25     memset(key,0,sizeof(key));
    26     memset(arr,0,sizeof(arr));
    27     while(!que.empty()) que.pop();
    28 }
    29 
    30 int bfs(){
    31     que.push({start_x,start_y,0,0});  // x,y,步数,状态
    32     vis[start_x][start_y][0]=1;
    33     while(!que.empty()){
    34         p=que.front(),que.pop();
    35         int x=p.x,y=p.y,num=p.num,state=p.state;
    36         if(x==end_x&&y==end_y){
    37             return num;
    38         }
    39         for(int i=0;i<4;i++){
    40             int xx=x+fx[i][0];
    41             int yy=y+fx[i][1];
    42             if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&arr[xx][yy]==0){
    43                 int state2=state|key[xx][yy];
    44                 if(vis[xx][yy][state2]) continue; //这个坐标的这个状态访问过 就不用在访问了 步数肯定比前面长
    45                 if((door[xx][yy]&state2)==door[xx][yy]){  //没有这扇门或者这扇门的钥匙已经获得了
    46                     vis[xx][yy][state2]=1;
    47                     que.push({xx,yy,num+1,state2});
    48                 }
    49 
    50             }
    51         }
    52     }
    53     return -1;
    54 }
    55 
    56 int main(){
    57     ios::sync_with_stdio(false);
    58     while(cin>>n>>m>>step){
    59         init();
    60         for(int i=1;i<=n;i++){
    61             cin>>name;
    62             int len=name.size();
    63             for(int j=0;j<len;j++){
    64                 if(name[j]=='@') start_x=i,start_y=j+1;
    65                 if(name[j]=='^') end_x=i,end_y=j+1;
    66                 if(name[j]=='*') arr[i][j+1]=1;
    67                 if(name[j]>='A'&&name[j]<='J'){
    68                     int zhi=name[j]-'A';
    69                     door[i][j+1]=(1<<zhi);   //(A-J)对应门的状态
    70                 }
    71                 if(name[j]>='a'&&name[j]<='j'){
    72                     int zhi=name[j]-'a';
    73                     key[i][j+1]=(1<<zhi);   //(a-j)钥匙的状态
    74                 }
    75             }
    76         }
    77         int flag=bfs();
    78         if(flag>=step) flag=-1;
    79         cout << flag << endl;
    80     }
    81     return 0;
    82 }
    View Code
     
  • 相关阅读:
    【巷子】:关于Apply、call、bind的详解
    关于this的指向问题
    SOA和微服务之间的区别
    业务系统如何微服务化
    微服务架构的理论基础
    每个架构师都应该研究下康威定律
    Rabbit MQ
    Scalability, Availability & Stability Patterns
    应用层协议
    SSO
  • 原文地址:https://www.cnblogs.com/qq-1585047819/p/11740477.html
Copyright © 2020-2023  润新知