zoukankan      html  css  js  c++  java
  • NYOJ 82 迷宫寻宝(一)

    迷宫寻宝(一)

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:4
     
    描述

    一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。

     
    输入
    输入可能会有多组测试数据(不超过10组)。
    每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
    .表示可以走的路
    S:表示ACM的出发点
    G表示宝藏的位置
    X表示这里有墙,ACM无法进入或者穿过。
    A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
    注意ACM只能在迷宫里向上下左右四个方向移动。

    最后,输入0 0表示输入结束。
    输出
    每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。
    样例输入
    4 4 
    S.X. 
    a.X. 
    ..XG 
    .... 
    3 4 
    S.Xa 
    .aXB 
    b.AG 
    0 0
    样例输出
    YES 
    NO
    来源
    POJ月赛改编
    上传者
    张云聪

    解题:压缩+dfs

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <set>
     4 #define LL long long
     5 using namespace std;
     6 char table[23][23];
     7 int rows,cols,totKey[5],hasKey[5],sx,sy;
     8 set<LL>vis;
     9 bool isVis(int x,int y){
    10     LL temp = 0;
    11     for(int i = 0; i < 5; i++)
    12         temp = (temp<<9)+hasKey[i];
    13     temp = (temp<<10)+(x<<5)+y;
    14     if(vis.count(temp)) return true;
    15     vis.insert(temp);
    16     return false;
    17 }
    18 bool dfs(int x,int y) {
    19     if(table[x][y] == 'X') return false;
    20     if(table[x][y] == 'G')
    21         return true;
    22     if(isVis(x,y)) return false;
    23     static  int dir[4][2] = {0,-1,0,1,-1,0,1,0};
    24     if(table[x][y] >= 'a' && table[x][y] <= 'e') {
    25         hasKey[table[x][y]-'a']++;
    26         table[x][y] = '.';
    27     } else if(table[x][y] >= 'A' && table[x][y] <= 'E') {
    28         if(hasKey[table[x][y]-'A'] < totKey[table[x][y]-'A'])
    29             return false;
    30     }
    31     char ch = table[x][y];
    32     table[x][y] = '.';
    33     for(int i = 0; i < 4; i++)
    34         if(dfs(x+dir[i][0],y+dir[i][1])) return true;
    35     if(table[x][y] != '.') table[x][y] = ch;
    36     return false;
    37 }
    38 int main() {
    39     int i,j;
    40     while(scanf("%d %d",&rows,&cols),rows||cols) {
    41         memset(totKey,0,sizeof(totKey));
    42         memset(hasKey,0,sizeof(hasKey));
    43         memset(table,'X',sizeof(table));
    44         for(i = 1; i <= rows; i++) {
    45             scanf("%s",table[i]+1);
    46             table[i][strlen(table[i])]='X';
    47             for(j = 1; j <= cols; j++) {
    48                 if(table[i][j] == 'S') {
    49                     table[sx = i][sy = j] = '.';
    50                 } else if(table[i][j] >= 'a' && table[i][j] <= 'e') {
    51                     totKey[table[i][j]-'a']++;
    52                 }
    53             }
    54         }
    55         vis.clear();
    56         for(i = 0; i < 5; i++)
    57             if(!totKey[i]) totKey[i] = 500;
    58         printf("%s
    ",dfs(sx,sy)?"YES":"NO");
    59     }
    60     return 0;
    61 }
    View Code
     
  • 相关阅读:
    预分频之三
    MySQL超时配置
    随机森林深入理解
    决策树算法——ID3
    指数平滑法
    最小二乘法的Java实现
    JS实战
    CSS布局实战
    Win7 Python开发环境搭建
    神经网络正向传播与反向传播公式
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/3854601.html
Copyright © 2011-2022 走看看