代码改变世界

【深度搜索】迷宫

2014-11-12 14:01  程序羊_宅在宿舍sicily  阅读(263)  评论(0)    收藏  举报
Description

 请写一个程序,先输入迷宫的维度M和N,然后输入这个M * N的迷宫,迷宫位置上的数值为0代表该位置可以通过,为1代表该位置有障碍不能通过,用深度优先搜索算法搜出一条从迷宫左上角到右下角的路径。规定搜索顺序为上、下、左、右。

如:

迷宫为2 * 2的:

00

00

搜索从左上角开始,到达右下角的路径应该是(0,0) (1,0) (1,1)

Input

 第一行是一个整数t,代表测试用例个数

接下来有t个迷宫,每个迷宫的格式如下:

第一行有两个整数M和N,中间用空格隔开,表示迷宫的维度,0 < M, N < 10

接下来有M行,每一行有N个元素,每个元素都是0或者1,注意元素之间是没有空格的

Output

 对于每一个用例,如果用深度优先搜索算法能搜索出路径,则输出搜索到的路径,路径的格式如下:

用坐标代表每个位置:(x,y),注意是没有空格的,每两个坐标之间有一个空格。

如:(0,0) (1,0) (1,1)表示从位置(0,0)走到位置(1,0)再走到位置(1,1)

如果不能搜索出路径,则输出no

sample input

1

2 2

00

00

sample output

(0,0) (1,0) (1,1)

 


 

我的第一道深度搜索算法题,贴出来纪念下。。。

 

深度搜索是从起点开始,搜索下一个节点,如果搜索到了就往下走,搜不到就返回上一个节点,当前节点标记为已经走过了。

我们用“栈"来存结点

举个例子就是

假设迷宫中0代表可以通行,1代表不可以通行

迷宫为

0 0 0  (0,0)(0,1)(0,2)

0 1 0  (1,0)(1,1) (1,2)

0 1 0  (2,0) (2,1) (2,2)

我们假设起点在左上角,终点在右上角,搜索顺序为上下左右。我们从起点开始搜索,发现可以向下走,于是就把处于(1,0)的这个结点入栈。然后标记当前节点为visited(表示已经走过了),然后我们发现还可以往下走,于是重复刚才的操作,把(2,0)这个节点入栈,之后我们发现无路可走,所以我们退回到前一个结点(出栈),然后把(2,0)这个结点标记为visited,表示这个点走过了,然后我们发现(1,0)这个结点也无路可走,所以我们退回到(0,0)。然后我们发现(0,0)可以向右走,于是我们重复之前的搜索操作,当我们走到(2,2)这个结点的时候,我们发现到达终点的了,所以就完成了搜索。

当然也可能存在所有的路都无法到达终点,那么我们就返回-1表示无法到达终点。


下面是题目的代码:

  1 #include <iostream>
  2 #include <string>
  3 #include <cstdlib>
  4 #include <stack>
  5 using namespace std;
  6 int maze[10][10];
  7 int visit[10][10];
  8 struct node {
  9   int x;
 10   int y;
 11   int get_x() {
 12     return x;
 13   }
 14   int get_y() {
 15     return y;
 16   }
 17 };
 18 
 19 bool ok(node a, int m, int n) {
 20   if (a.x >= 0 && a.x < m && a.y >=0 && a.y < n && maze[a.x][a.y] == 0 && visit[a.x][a.y] == 0) return true;
 21   else return false;
 22 }
 23 
 24 void print(stack<node> &a) {
 25   stack<node> b;
 26   while (!a.empty()) {
 27     b.push(a.top());
 28     a.pop();
 29   }
 30   while (b.size() > 1) {
 31     cout << "(";
 32     node p = b.top();
 33     cout << p.x << "," << p.y << ") ";
 34     b.pop();
 35   }
 36   node p = b.top();
 37   cout << "(" << p.x << "," << p.y << ")\n";
 38 }
 39 
 40 void path(int x1, int y1, int m, int n) {
 41   visit[0][0] = 1;
 42   stack<node> a;
 43   node start;
 44   start.x = x1;
 45   start.y = y1;
 46   a.push(start);
 47   bool find = false;
 48   while (!a.empty()) {
 49     node cur = a.top();
 50     if (cur.x == m - 1 && cur.y == n - 1) {
 51       print(a);
 52       find = true;
 53       break;
 54     }
 55     node up;
 56     up.x = cur.x - 1;
 57     up.y = cur.y;
 58     node down;
 59     down.x = cur.x + 1;
 60     down.y = cur.y;
 61     node left;
 62     left.x = cur.x;
 63     left.y = cur.y - 1;
 64     node right;
 65     right.x = cur.x;
 66     right.y = cur.y + 1;
 67     if (ok(up,m,n)) {
 68       a.push(up);
 69       visit[up.x][up.y] = 1;
 70     }
 71     else if (ok(down,m,n)) {
 72       a.push(down);
 73       visit[down.x][down.y] = 1;
 74     }
 75     else if (ok(left,m,n)) {
 76       a.push(left);
 77       visit[left.x][left.y] = 1;
 78     }
 79     else if (ok(right,m,n)) {
 80       a.push(right);
 81       visit[right.x][right.y] = 1;
 82     } else {
 83       a.pop();
 84     }
 85   }
 86   if (!find) cout << "no\n";
 87 }
 88 
 89 int main () {
 90   int t;
 91   cin >> t;
 92   while (t--) {
 93     int M, N;
 94     cin >> M >> N;
 95     for (int i = 0; i < M; i++) {
 96       for (int j = 0; j < N; j++) {
 97         visit[i][j] = 0;
 98       }
 99     }
100     for (int i = 0; i < M; i++) {
101       string str;
102       cin >> str;
103       for (int j = 0; j < str.size(); j++) {
104         maze[i][j] = str[j] - '0';
105       }
106     }
107     path(0,0,M,N);
108   }
109  // system("pause");
110 }
View Code