迷宫

原题粘贴:

1215:迷宫


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 13252     通过数: 3886 

【题目描述】

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。

【输入】

第1行是测试数据的组数k,后面跟着k组输入。每组测试数据的第1行是一个正整数n (1 ≤ n ≤ 100),表示迷宫的规模是n * n的。接下来是一个n * n的矩阵,矩阵中的元素为.或者#。再接下来一行是4个整数ha, la, hb, lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha, la, hb, lb全部是从0开始计数的。

【输出】

k行,每行输出对应一个输入。能办到则输出“YES”,否则输出“NO”。

【输入样例】

2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0

【输出样例】

YES
NO


很典型的搜索回溯题(DFS),如果非要广度优先搜索(BFS),也无所谓(耸肩),看到搜索很自然的想到坐标别告诉我不知道坐标是什么,尽管我也是学了深度搜索才知道的。那就,再科普一下?

往下看

 



 (图丑勿喷)其实这很好理解,设出发点(原点?)坐标为(0,0),那么这个往右走一步便是(0,-1),往上走是(1,0)往右走是(0,1),向下便是(1,0)就是在相应的方向上对于x和y进行加1或减1处理


科普完毕

那么,了解了坐标后,就可以得出一下两个表示坐标的数组:

1 int dx[4]={0,1,0,-1},
2     dy[4]={1,0,-1,0}

 

然后就是输入预处理,将每组数据的地图进行初始化,用0,1表示能不能走以及有没有走过(要注意,如果出发点就是不能走的,直接退出即可,不必进行递归Dfs),同时,添加一个Flag判断数据是否有解,若有解,输出“YES”,否则一律“NO"(每次输入的地图都需要更新map中的0,1的情况):

 1 cin>>n;
 2     while (n--){
 3         
 4         cin>>m;
 5         memset(boo_map,true,sizeof(boo_map));//初始化地图
 6         flag=false;
 7         for(int i=0;i<m;i++)
 8            for(int j=0;j<m;j++){
 9                cin>>chr;
10                   if(chr=='#')boo_map[i][j]=false;//标注不能走的地方
11            }
12         cin>>x1>>y1>>x2>>y2;
13         Dfs(x1,y1);
14         if(!flag)cout<<"NO"<<endl;//无解输出”NO"
15     }

接下来就是最重要的搜索(Dfs),也就是本题的核心:

1. 判断最终是否抵达终点,若抵达,输出“YES",Flag变为1,跳出递归程序段

2. 若不满足条件,枚举四个方向(即dx&dy),依次用当前坐标x,y去加,若满足边界条件(即:x+dx[i]>=0&&x+dx[i]<m&&y+dy[i]>=0&&y+dy[i]<m&&boo_map[x+dx[i]][y+dy[i]])

3. 将走过的路设为0

4. 递归下一层

5. 回溯(可以不回溯)

便可得:

 1 void Dfs(int x,int y){
 2     
 3     if(x==x2&&y==y2){//1
 4         cout<<"YES"<<endl;
 5         flag=true;
 6         return ;
 7     }
 8     else
 9     for(int i=0;i<4;i++){//2
10         if(x+dx[i]>=0&&x+dx[i]<m&&y+dy[i]>=0&&y+dy[i]<m&&boo_map[x+dx[i]][y+dy[i]]){
11             boo_map[x+dx[i]][y+dy[i]]=false;//3
12             Dfs(x+dx[i],y+dy[i]);//4
13         }
14     }
15     
16 }

整合一下,便可以AC啦!

 

Code防作弊系统已添加

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int dx[4]={0,1,0,-1},
 6     dy[4]={1,0,-1,0};
 7 bool boo_map[1000][1000]={true},flag=false;
 8 int m,n;
 9 int x1,x2,y1,y2;
10 void Dfs(int x,int y){
11     
12     if(x==x2&&y==y2){
13         cout<<"YES"<<endl;
14         flag=true;
15         return ;
16     }
17     else
18     for(int i=0;i<4;i++){
19         if(x+dx[i]>=0&&x+dx[i]<m&&y+dy[i]>=0&&y+dy[i]<m&&boo_map[x+dx[i]][y+dy[i]]){
20             boo_map[x+dx[i]][y+dy[i]]=false;
21             Dfs(x+dx[i],y+dy[i]);
22         }
23     }
24     
25 }
26 
27 int main(){
28     int n;
29     char chr;
30     cin>>n;
31     while (n--){
32         
33         cin>>m;
34         memset(boo_map,true,sizeof(boo_map));
35         flag=false;
36         for(int i=0;i<m;i++)
37            for(int j=0;j<m;j++){
38                cin>>chr;
39                   if(chr=='#')boo_map[i][j]=false;
40            }
41         cin>>x1>>y1>>x2>>y2;
42         Dfs(x1,y1);
43         if(!flag)cout<<"NO"<<endl;
44     }
45     
46 }

 

THE END

 

PS:戳一下↓[关注我]↓再走呗

posted @ 2019-08-04 19:27  DreamShadow  阅读(702)  评论(0编辑  收藏  举报