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

    胜利大逃亡(续)

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

    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

    思路:BFS,用二进制表示钥匙,那么每一个点用f[i][j][k] 表示是i.j这个点,k的二进制上的1表示拥有哪一把钥匙

    总复杂度2^10*20*20

      1 /*
      2 Author:wuhuajun
      3 */
      4 #include <cmath>
      5 #include <cstdio>
      6 #include <algorithm>
      7 #include <cstring>
      8 #include <string>
      9 #include <cstdlib>
     10 #include <queue>
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 typedef double dd;
     15 const int maxn=22;
     16 const int dx[]={1,-1,0,0};
     17 const int dy[]={0,0,1,-1};
     18 char s[maxn][maxn],ch;
     19 bool f[maxn][maxn][(1<<10)+10];
     20 struct qq
     21 {
     22     int x,y,v;
     23 } ya,pu;
     24 queue<qq> q;
     25 int step,l,n,m,t,xx,yy,sx,sy,ex,ey,deadline,pos;
     26 bool flag;
     27 
     28 
     29 void close()
     30 {
     31 exit(0);
     32 }
     33 bool reach()
     34 {
     35     if (xx==ex && yy==ey)
     36     {
     37         if (step<deadline)
     38             printf("%d
    ",step);
     39         else
     40             printf("-1
    ");
     41         flag=true;
     42         return true;
     43     }
     44     return false;
     45 }
     46 
     47 void print()
     48 {
     49     for (int i=8;i>=1;i--)
     50         printf("%d",pos & (i<<1));
     51     puts("");
     52 }
     53 
     54 void pushin()
     55 {
     56     pu=ya;
     57     pu.x=xx; pu.y=yy;
     58     if (t!=0)
     59         pu.v=ya.v | (1<<(t-1));
     60     q.push(pu);
     61 }
     62 
     63 void judge()
     64 {
     65     if (!(1<=xx && xx<=n && 1<=yy && yy<=m)) return;
     66     ch=s[xx][yy];
     67     if (ch=='*') return;//wall
     68     if (ch=='.' || ch=='@')
     69     {
     70         t=0;
     71         if (f[xx][yy][ya.v]) return;
     72         f[xx][yy][ya.v]=true;
     73         pushin();
     74         return;
     75     }
     76     if ('a'<=ch && ch<='j') //key
     77     {
     78         t=ch-'a'+1;
     79         pos=ya.v | (1<<(t-1));
     80         if (f[xx][yy][pos]) return;//是否到过(xx,yy)这个点
     81         f[xx][yy][pos]=true;
     82         pushin();
     83     }
     84     else
     85     {                     //door
     86         t=ch-'A'+1;
     87         if ((ya.v & (1<<(t-1)))==0) return;//在(ya.x,ya.y)点上钥匙不能开门
     88         if (f[xx][yy][ya.v]) return;
     89         f[xx][yy][ya.v]=true;
     90         t=0;
     91         pushin();
     92     }
     93 }
     94 
     95 void work()
     96 {
     97     memset(f,false,sizeof(f));
     98     while (!q.empty()) q.pop();
     99     step=0; flag=true;
    100     //////////////////
    101     f[sx][sy][0]=true;
    102     ya.x=sx;
    103     ya.y=sy;
    104     ya.v=0;
    105     q.push(ya);
    106     while (!q.empty())
    107     {
    108         step++;
    109         //printf("Step:%d
    -----------------------
    ",step-1);
    110         l=q.size();
    111         while (l--)
    112         {
    113             ya=q.front();
    114             q.pop();
    115         //    printf("x:%d y:%d v:%d
    ",ya.x,ya.y,ya.v);
    116             for (int i=0;i<4;i++)
    117             {
    118                 xx=dx[i]+ya.x;
    119                 yy=dy[i]+ya.y;
    120                 if (reach()) return;
    121                 judge();
    122             }
    123         }
    124     }
    125     printf("-1
    ");
    126 }
    127 
    128 
    129 void init()
    130 {
    131     while (scanf("%d %d %d",&n,&m,&deadline)!=EOF)
    132     {
    133         for (int i=1;i<=n;i++)
    134         {
    135             scanf("%s",s[i]);
    136             for (int j=m-1;j>=0;j--)
    137                 s[i][j+1]=s[i][j];
    138             s[i][0]='';
    139         }
    140         for (int i=1;i<=n;i++)
    141             for (int j=1;j<=m;j++)
    142             {
    143                 if (s[i][j]=='@')
    144                 {    
    145                     sx=i;sy=j;
    146                 }
    147                 if (s[i][j]=='^')
    148                 {
    149                     ex=i; ey=j;
    150                 }
    151             }
    152         work();
    153     }
    154 }
    155 
    156 int main ()
    157 {
    158     init();
    159     close();
    160     return 0;
    161 }
  • 相关阅读:
    canvas直线学习
    移动端页面练习
    IOS 本地推送(UILocalNotification)
    IOS 社交分享
    IOS 通讯录 (访问,添加,修改)
    IOS 蓝牙(GameKit、Core Bluetooth)
    IOS 获取更多的设备信息
    IOS 摇一摇的方法
    IOS Core Motion、UIAccelerometer(加速计使用)
    IOS UIDevice距离传感器(打开 关闭)
  • 原文地址:https://www.cnblogs.com/cssystem/p/3335180.html
Copyright © 2011-2022 走看看