首页 > 代码库 > 第四章 搜索(深度、广度搜索、全排列、走迷宫、再解炸弹人、宝岛探险、水管工游戏)

第四章 搜索(深度、广度搜索、全排列、走迷宫、再解炸弹人、宝岛探险、水管工游戏)

一、深度优先搜索DFS

  深度优先搜索DFS的关键思想是:当下应该怎么做(每个方法都试一遍),这一步解决后,进入下一步,下一步的解决方法和这一步的解决方法是一样的

  DFS的基本模型

  void dfs(int step)

  {

    判断边界

    尝试每一种可能  for(i=1;i<=n;i++)

    {

      继续下一步 dfs(step+1)

    }

    返回

  }

  1.1全排列

技术分享
 1 //输入一个数n
 2 //输出1-n的全排列
 3 #include <stdio.h>
 4 int n, book[10], a[10];
 5 void dfs(int step)
 6 {
 7     int i;
 8     if (step > n)
 9     {
10         for (i = 1;i <= n;i++)
11         {
12             printf("%d ",a[i]);
13         }
14         printf("\n");
15         return;
16     }
17     for (i = 1;i <= n;i++)
18     {
19         if (book[i] == 0)
20         {
21             a[step] = i;
22             book[i] = 1;
23             dfs(step+1);
24             book[i] = 0;
25         }
26     }
27     return;
28 }
29 int main()
30 {
31     scanf("%d",&n);
32     dfs(1);
33     return 0;
34 }
View Code

  1.2两个三位数相加的结果是三位数,这9个数字各不相同,_ _ _ + _ _ _ = _ _ _

技术分享
 1 #include <stdio.h>
 2 int total = 0;
 3 int book[10], a[10];
 4 void dfs(int step)
 5 {
 6     int i;
 7     if (step == 10)
 8     {
 9         if (100 * (a[1] + a[4]) + 10 * (a[2] + a[5]) + a[3] + a[6] == 100 * a[7] + 10 * a[8] + a[9])
10         {
11             total++;
12             printf("%d%d%d + %d%d%d = %d%d%d\n",a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
13         }
14         return;
15     }
16     for (i = 1;i < 10;i++)
17     {
18         if (book[i] == 0)
19         {
20             book[i] = 1;
21             a[step] = i;
22             dfs(step+1);
23             book[i] = 0;
24         }
25     }
26     return;
27 }
28 int main()
29 {
30     dfs(1);
31     printf("%d\n",total/2);
32     return 0;
33 }
View Code

  1.3走迷宫,解救小哈

技术分享
 1 #include <stdio.h>
 2 int n, m, map[10][10], book[10][10],endx, endy,minstep=978978;
 3 void dfs(int x, int y, int step)
 4 {
 5     int i,tx,ty;
 6     int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
 7     if (x == endx&&y == endy)
 8     {
 9         if (minstep > step)
10             minstep = step;
11         return;
12     }
13     for (i = 0;i < 4;i++)
14     {
15         tx = x + next[i][0];
16         ty = y + next[i][1];
17         if (tx<1 || ty<1 || tx>n || ty>m)
18             continue;
19         if (map[tx][ty] == 0 && book[tx][ty] == 0)
20         {
21             book[tx][ty] = 1;
22             dfs(tx,ty,step+1);
23             book[tx][ty] = 0;
24         }
25     }
26     return;
27 }
28 int main()
29 {
30     int i, j, startx, starty;
31     scanf("%d%d",&n,&m);
32     for (i = 1;i <= n;i++)
33     {
34         for (j = 1;j <= m;j++)
35         {
36             scanf("%d",&map[i][j]);
37         }
38     }
39     scanf("%d%d%d%d",&startx,&starty,&endx,&endy);
40 
41     dfs(startx,starty,0);
42     
43     printf("%d\n",minstep);
44     return 0;
45 }
View Code

 二、广度优先搜索BFS

  深度优先搜索DFS——递归

  广度优先搜索BFS——队列 

  继续走迷宫 

技术分享
 1 #include <stdio.h>
 2 int n, m, endx, endy;
 3 int map[10][10], book[10][10];
 4 struct node
 5 {
 6     int x;
 7     int y;
 8     int step;
 9 };
10 void bfs(int startx,int starty)
11 {
12     struct node queue[100];
13     int head, tail;
14     int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
15     int i, tx, ty, flag = 0;
16     head = 1;tail = 1;
17     queue[tail].x = startx;
18     queue[tail].y = starty;
19     queue[tail].step = 0;
20     tail++;
21     book[startx][starty] = 1;
22     while (head<tail)
23     {
24         for (i = 0;i < 4;i++)
25         {
26             tx = queue[head].x + next[i][0];
27             ty = queue[head].y + next[i][1];
28             if (tx<1 || ty<1 || tx>n || ty>m)
29             {
30                 continue;
31             }
32             if (map[tx][ty] == 0 && book[tx][ty] == 0)
33             {
34                 book[tx][ty] = 1;
35                 queue[tail].x = tx;
36                 queue[tail].y = ty;
37                 queue[tail].step = queue[head].step + 1;
38                 tail++;
39             }
40             if (tx == endx&&ty == endy)
41             {
42                 flag = 1;
43                 break;
44             }
45         }
46         if (flag == 1)
47             break;
48         head++;
49     }
50     printf("%d\n",queue[tail-1].step);
51 
52 }
53 int main()
54 {
55     int i, j,startx,starty;
56     scanf("%d%d",&n,&m);
57     for (i = 1;i <= n;i++)
58     {
59         for (j = 1;j <= m;j++)
60         {
61             scanf("%d",&map[i][j]);
62         }
63     }
64     scanf("%d%d%d%d",&startx,&starty,&endx,&endy);
65     bfs(startx,starty);
66     return 0;
67 }
View Code

三、再解炸弹人

  现在炸弹不是想放在那里就能放在那里的了,必须由小人能够走到的地方才能放置炸弹。比如下面这个例子小人默认站在(3,3)这个位置。请问放在何处最多可以消灭多个敌人。

  技术分享 

输入

13 13 3 3
#############
#GG.GGG#GGG.#
###.#G#G#G#G#
#.......#..G#
#G#.###.#G#G#
#GG.GGG.#.GG#
#G#.#G#.#.#.#
##G...G.....#
#G#.#G###.#G#
#...G#GGG.GG#
#G#.#G#G#.#G#
#GG.GGG#G.GG#
#############
输出
将炸弹放置在(7,11)处,最多可以消灭10个敌人。
技术分享
  1 #include <stdio.h>
  2 char map[20][20];
  3 int n, m, book[20][20];
  4 int max=0, maxx, maxy;
  5 struct node
  6 {
  7     int x;
  8     int y;
  9 };
 10 int fun(int x,int y)
 11 {
 12     int sum = 0, k;
 13     k = x;
 14     while (map[k][y] != #&&k >= 0)
 15     {
 16         if (map[k][y] == G)
 17             sum++;
 18         k--;
 19     }
 20     k = x;
 21     while (map[k][y] != #&&k < n)
 22     {
 23         if (map[k][y] == G)
 24             sum++;
 25         k++;
 26     }
 27     k = y;
 28     while (map[x][k] != #&&k >= 0)
 29     {
 30         if (map[x][k] == G)
 31             sum++;
 32         k--;
 33     }
 34     k = y;
 35     while (map[x][k] != #&&k <m)
 36     {
 37         if (map[x][k] == G)
 38             sum++;
 39         k++;
 40     }
 41     return sum;
 42 }
 43 void dfs(int x,int y)
 44 {
 45     int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
 46     int i,tx,ty;
 47     int sum = fun(x, y);
 48     if (max < sum)
 49     {
 50         max = sum;
 51         maxx = x;
 52         maxy = y;
 53     }
 54     for (i = 0;i < 4;i++)
 55     {
 56         tx = x + next[i][0];
 57         ty = y + next[i][1];
 58         if (tx < 0 || tx >= n || ty < 0 || ty >= m)
 59             continue;
 60         if (map[tx][ty] == .&&book[tx][ty] == 0)
 61         {
 62             book[tx][ty] = 1;
 63             dfs(tx,ty);
 64         }
 65     }
 66     return;
 67 }
 68 void bfs(int x,int y)
 69 {
 70     struct node queue[200];
 71     int head, tail,i,tx,ty,sum;
 72     int next[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
 73     head = 0;
 74     tail = 0;
 75     queue[tail].x = x;
 76     queue[tail].y = y;
 77     tail++;
 78     while (head < tail)
 79     {
 80         for (i = 0;i < 4;i++)
 81         {
 82             tx = queue[head].x + next[i][0];
 83             ty = queue[head].y + next[i][1];
 84             if (tx < 0 || tx >= n || ty < 0 || ty >= m)
 85                 continue;
 86             if (map[tx][ty] == .&&book[tx][ty] == 0)
 87             {
 88                 queue[tail].x = tx;
 89                 queue[tail].y = ty;
 90                 tail++;
 91                 sum = fun(tx, ty);
 92                 book[tx][ty] = 1;
 93                 if (sum > max)
 94                 {
 95                     max = sum;
 96                     maxx = tx;
 97                     maxy = ty;
 98                 }
 99             }
100         }
101         head++;
102     }
103 }
104 int main()
105 {
106     int i,startx,starty;
107     scanf("%d%d%d%d",&n,&m,&startx,&starty);
108     getchar();
109     for (i = 0;i < n;i++)
110         gets(map[i]);
111     max = fun(startx,starty);
112     maxx = startx;
113     maxy = starty;
114     book[startx][starty] = 1;
115     //dfs(startx,starty);
116     bfs(startx,starty);
117     printf("max=%d,x=%d,y=%d\n",max,maxx,maxy);
118     return 0;
119 }
View Code

四、宝岛探险

技术分享

 

问题一
小哼降落后,所在岛屿的面积大小
输入地图和降落位置(从序号1开始)
输出降落所在位置的岛屿面积
例子
输入:
10 10 6 8
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
输出:
38
 
 
问题二
小哼降落后,所在岛屿的面积大小
输入地图和降落位置(从序号1开始)
输出降落所在位置的岛屿
例子
输入:
10 10 6 8
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
输出:
   1   2   1   0   0   0   0   0   2   3
   3   0   2   0  -1  -1  -1   0   1   2
   4   0   1   0  -1  -1  -1  -1   0   1
   3   2   0   0   0  -1  -1  -1   0   0
   0   0   0   0   0   0  -1  -1  -1   0
   0  -1  -1  -1   0  -1  -1  -1  -1   0
   0  -1  -1  -1  -1  -1  -1  -1  -1   0
   0   0  -1  -1  -1  -1  -1  -1   0   0
   0   0   0  -1  -1  -1  -1   0   1   2
   0   0   0   0   0   0   0   0   1   0
问题三
求出地图中小岛个数
例子
输入:
10 10
1 2 1 0 0 0 0 0 2 3
3 0 2 0 1 2 1 0 1 2
4 0 1 0 1 2 3 2 0 1
3 2 0 0 0 1 2 4 0 0
0 0 0 0 0 0 1 5 3 0
0 1 2 1 0 1 5 4 3 0
0 1 2 3 1 3 6 2 1 0
0 0 3 4 8 9 7 5 0 0
0 0 0 3 7 8 6 0 1 2
0 0 0 0 0 0 0 0 1 0
输出:
  -1  -1  -1   0   0   0   0   0  -2  -2
  -1   0  -1   0  -3  -3  -3   0  -2  -2
  -1   0  -1   0  -3  -3  -3  -3   0  -2
  -1  -1   0   0   0  -3  -3  -3   0   0
   0   0   0   0   0   0  -3  -3  -3   0
   0  -3  -3  -3   0  -3  -3  -3  -3   0
   0  -3  -3  -3  -3  -3  -3  -3  -3   0
   0   0  -3  -3  -3  -3  -3  -3   0   0
   0   0   0  -3  -3  -3  -3   0  -4  -4
   0   0   0   0   0   0   0   0  -4   0
 
 
 
   
 

五、

第四章 搜索(深度、广度搜索、全排列、走迷宫、再解炸弹人、宝岛探险、水管工游戏)