zoukankan      html  css  js  c++  java
  • 胜利大逃亡(续)

    胜利大逃亡(续)

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


    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
     
    View Code
      1 #include<iostream>
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<queue>
      5 using namespace std;
      6 int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}};
      7 struct node
      8 {
      9     int x,y;
     10     int cnt;
     11     int time;
     12 };
     13 char map[22][22];
     14 int flag[2048][22][22];
     15 int x1,y1;
     16 int row,col,t;
     17 queue<node>q;
     18 
     19 bool judge(node tp)
     20 {
     21     if(tp.x<0 || tp.x>=row || tp.y<0 || tp.y>=col || map[tp.x][tp.y]=='*')
     22         return false;
     23     return true;
     24 }
     25 
     26 int bfs()
     27 {
     28     while(!q.empty())
     29         q.pop();
     30     node temp,p;
     31     int i,cc;
     32     p.x=x1;
     33     p.y=y1;
     34     p.cnt=0;
     35     p.time=0;
     36     q.push(p);
     37     while(!q.empty())
     38     {
     39         p=q.front();
     40         q.pop();
     41         if(p.time>=t-1)
     42             return -1;
     43         for(i=0;i<4;i++)
     44         {
     45             temp=p;
     46             temp.x+=dir[i][0];
     47             temp.y+=dir[i][1];
     48             temp.time=p.time+1;
     49             temp.cnt=p.cnt;
     50             if(!judge(temp))
     51                 continue;
     52             if(map[temp.x][temp.y]=='^')
     53             {
     54                 return temp.time;
     55             }
     56             if(map[temp.x][temp.y]=='@' || map[temp.x][temp.y]=='.')
     57             {
     58                 if(!flag[temp.cnt][temp.x][temp.y])
     59                 {
     60                     flag[temp.cnt][temp.x][temp.y]=1;
     61                     q.push(temp);
     62                 }
     63                 continue;
     64             }
     65             if(map[temp.x][temp.y]>='A' && map[temp.x][temp.y]<='J' && !flag[temp.cnt][temp.x][temp.y])
     66             {
     67                 cc=temp.cnt;
     68                 if((cc>>(map[temp.x][temp.y]-'A')) & 1)
     69                 {
     70                     flag[temp.cnt][temp.x][temp.y]=1;
     71                     q.push(temp);
     72                 }
     73                 continue;
     74             }
     75             if(map[temp.x][temp.y]>='a' && map[temp.x][temp.y]<='j')
     76             {
     77                 cc=1<<(map[temp.x][temp.y]-'a');
     78                 temp.cnt=cc | temp.cnt;
     79                 if(!flag[temp.cnt][temp.x][temp.y])
     80                 {
     81                     flag[temp.cnt][temp.x][temp.y]=1;
     82                     q.push(temp);
     83                 }
     84                 continue;
     85             }
     86         }
     87     }
     88     return -1;
     89 }
     90 
     91 int main()
     92 {
     93     while(~scanf("%d%d%d",&row,&col,&t))
     94     {
     95         int i,j;
     96         bool ff=false;
     97         for(i=0;i<row;i++)
     98         {
     99             scanf("%s",map[i]);
    100             if(!ff)
    101             {
    102                 for(j=0;j<col;j++)
    103                 {
    104                     if(map[i][j]=='@')
    105                     {
    106                         x1=i;
    107                         y1=j;
    108                         ff=true;
    109                         break;
    110                     }
    111                 }
    112             }
    113         }
    114         memset(flag,0,sizeof(flag));
    115         flag[0][x1][y1]=1;
    116         int res=bfs();
    117         printf("%d\n",res);
    118     }
    119     return 0;
    120 }

    这是一道简单的状态标记广搜题目,刚开始卡死在状态那个地方,后来想通了,题目中最多拥有10把钥匙,也就是2^10方(十位二进制中的每一位代表着不同钥匙,0代表没有拥有,1代表拥有此钥匙)作为状态标记,所以定义一个三维的flag[][][]标记函数,进行普通的广搜,注意遇到小写字母的时候记得进行左移 再与前一个状态值进行或运算,例如,假设已经用了A 门的要是,状态此时因该是0000000001,意思是拥有了a,如果下一次遇到了J门的钥匙,也就是j,那就应该是(1<<10) | (0000000001),那么此时的状态应该是1000000001,当遇到已经拥有钥匙的门的时候再进行右移运算,例如下一次遇到J门时,我们应该先将1000000001右移10位再与 1进行(&)与运算,如果拥有J门的钥匙 应该是1&1=1 ,是真值,可以通过,如果没有,则0&1=0,是假值,则无法通过。

    剩下的就是一般的左右上下的移动 判断。

    值得让我吸取教训的是,在定义了一个队列的时候,在使用前必须判断队列里面是否为空,如果不为空,则必须置空,也就是这里让我WA了两三次,就是少了

    while(!q.empty())
    q.pop();

    这一句。

    写下这篇来告诫自己下次小心。

     
  • 相关阅读:
    了解 NoSQL 的必读资料
    关于什么时候用assert(断言)的思考
    这次见到了一些大侠
    NetBeans 时事通讯(刊号 # 87 Jan 12, 2010)
    动态链接库dll,静态链接库lib, 导入库lib
    新女性十得 写得了代码,查得出异常
    记录系统乱谈
    新女性十得 写得了代码,查得出异常
    fullpage.js禁止滚动
    RunningMapReduceExampleTFIDF hadoopclusternet This document describes how to run the TFIDF MapReduce example against ascii books. This project is for those who wants to experiment hadoop as a skunkworks in a small cluster (110 nodes) Google Pro
  • 原文地址:https://www.cnblogs.com/ouyangduoduo/p/3026047.html
Copyright © 2011-2022 走看看