• 35-迷宫寻宝(一)-NYOJ82


    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=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月赛改编
    上传者
    张云聪
    #include <iostream>
    #include <cstring>
    using namespace std;
    char map[23][23];
    int visit[23][23];
    int yao[10];
    int n, m;
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int isagain;
    int flag = 0;
    
    int dfs(int x, int y){
    	if(map[x][y] == 'G'){
    		flag = 1;
    		return 1;
    	}	
    	for(int i = 0; i < 4; i++){
    		int xx = x + dx[i];
    		int yy = y + dy[i];
    		if(xx >= 0 && xx < n && yy >= 0 && yy < m){
    			if(!visit[xx][yy]){ 
    				visit[xx][yy] = 1;
    				if(map[xx][yy] == '.'){
    					if(dfs(xx, yy))
    						return 1;
    				}
    				else if(map[xx][yy] >= 'a' && map[xx][yy] <= 'z'){
    					yao[map[xx][yy] - 'a']--;   //找到对应钥匙了,相当于打开此门所需要的钥匙减一 
    					if(yao[map[xx][yy]] == 0){  //可以打开对应的门了 
    						isagain = 1;			//所以可以给他一次重新搜索的机会 
    					}
    					map[xx][yy] = '.';
    					if(dfs(xx, yy))
    						return 1;
    				}
    				else if(map[xx][yy] >= 'A' && map[xx][yy] <= 'E'){ //刚开始写成了A到G,所以永远到不了G的判断 
    					if(yao[map[xx][yy] - 'A'] == 0){
    //						cout << "open: " << map[xx][yy] << endl;
    						map[xx][yy] = '.'; 
    						if(dfs(xx, yy))
    							return 1;
    					}
    				}
    				else if(map[xx][yy] == 'G'){
    //					cout << "G" << endl;
    					if(dfs(xx, yy))
    						return 1;
    				}	
    				visit[xx][yy] = 0;
    			} 
    		} 
    	}
    	return 0;
    }
    
    int main(){
    	std::ios::sync_with_stdio(false);
    	while(cin >> n >> m){
    		memset(visit, 0, sizeof(visit));
    		memset(yao, 0, sizeof(yao));
    		if((n == 0 && m == 0))
    			break;
    		int sx, sy; 
    		for(int i = 0; i < n; i++){
    			for(int j = 0; j < m; j++){
    				cin >> map[i][j];
    				if(map[i][j] >= 'a' && map[i][j] <= 'z'){
    					yao[map[i][j] - 'a']++; //记录每个门所需要的钥匙 
    				}
    				else if(map[i][j] == 'S'){  //记录起点 
    					sx = i, sy = j;
    				}
    			}
    		}
    		flag = 0;
    		isagain = 1;
    		while(isagain){		//可能可以打开门,重新尝试一次 
    			isagain = 0; 
    			memset(visit, 0, sizeof(visit));  //因为dfs里面有许多return,打断了还原0 
    			visit[sx][sy] = 1;
    			flag = dfs(sx, sy);
    			if(flag)
    				break;
    		}
    		if(flag)
    			cout << "YES" << endl;		
    		else
    			cout << "NO" << endl;
    	}
    	return 0;
    } 
    /*
    5 5
    SXaXG
    .X.X.
    .X.X.
    .X.XA
    .....
    5 5
    aE..S
    bXX.c
    XX.CX
    GBA.B
    XXe.e
    5 5
    a...a
    XX.XX
    bXSXG
    .XAXB
    .....
    5 5
    .X.XG
    Sa..A
    .b.Xc
    XX..B
    bC...
    5 5
    .X.XG
    Sb..B
    .b.Xc
    XX..B
    bC...
    1 10
    S.aAbBcC.G
    0 0
    */
    

      

  • 相关阅读:
    Textbox 自动调节高度
    Sharepoint 2010 备份与恢复 (二)
    Sharepoint 2010 备份与恢复 (一)
    Sharepoint 查看站点集是否锁住状态
    Sharepoint安装Infopath Service
    php分页显示类——在线拍卖行(1)
    php一个比较基础的文件上传的代码
    html表单的type属性
    JQuery简单表单验证
    最近的一些思考,感悟和理解。
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/8661100.html
Copyright © 2020-2023  润新知