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

一、深度优先搜索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 }

  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 }

  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 }

二、广度优先搜索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 }

三、再解炸弹人

  现在炸弹不是想放在那里就能放在那里的了,必须由小人能够走到的地方才能放置炸弹。比如下面这个例子小人默认站在(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 }

四、宝岛探险

问题一

小哼降落后,所在岛屿的面积大小

输入地图和降落位置(从序号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

 

五、

时间: 2024-10-10 00:58:01

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

第四章、万能的搜索

第一节.深度优先搜索p78 输出全排列的 dfs 方法 #include <stdio.h> int a[10],book[10],n; void dfs(int step) { int i; if(step==n+1) { for(i=1;i<=n;i++) printf("%d",a[i]); printf("\n"); return; } for(i=1;i<=n;i++) { if(book[i]==0) { a[step]=i; b

迷宫问题解决方法:分别基于深度搜索和广度搜索的思想来实现

本文针对迷宫问题,探讨解决思路并给出实现代码.在本文中,采用的图的深度优先搜索和广度优先搜索两种方法分别对迷宫的路径进行了求解. 首先来看迷宫问题的描述,可以参考此处,简而言之就是,通过一个二维数组(int型)来表示迷宫,迷宫中0表示可行,1表示不可行.在本文的实现中,可以输入给定迷宫,定义迷宫入口和出口,并查找迷宫路径. 总体的描述:在本文中,定义了结构体Node,用于存放节点信息,而Node内只有两个变量,标识节点的行坐标与列坐标.定义了迷宫类maze,并分别定义了相应的get.set函数,

C语言实现的图的深度搜索与广度搜索程序

/* 上机试验5-图的建立和遍历 1)建立[无向][非连通]图的邻接表存储结构,要求顶点个数不少于15个. 2)用DFS及BFS对此邻接表进行遍历,打印出两种遍历的顶点访问顺序. 3)给定图中任意两个顶点v1和v2及整数k,判断是否存在从v1到v2的路径长度为k的简单路径,若有打印出路径上的顶点序列(要求路径上不含回路). 进一步:找出从v1到v2的所有路径长度为k的[简单]路径.(简单路径是指:顶点序列中不含[重现]的顶点的路径.) */ #include<memory> #include&

第四章 搜索

深度优先搜索 计算数的全排列 #include<iostream> #include<vector> #include<iterator> #include<algorithm> using namespace std; /* 将1-n全排列,目前到了从左到右的step位 box:从左到右存储 flags:1-n哪些已经用了 */ void dfs(vector<int> & box, vector<bool> & f

深度优先搜索和广度优先搜索的深入讨论

一.深度优先搜索和广度优先搜索的深入讨论 (一)深度优先搜索的特点是: (1)从上面几个实例看出,可以用深度优先搜索的方法处理的题目是各种各样的.有的搜索深度是已知和固定的,如例题2-4,2-5,2-6:有的是未知的,如例题2-7.例题2-8:有的搜索深度是有限制的,但达到目标的深度是不定的. 但也看到,无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生规则以及输出要求. (2)深

深度优先搜索和广度优先搜索的比较与分(转)

深度优先搜索和广度优先搜索的深入讨论   (一)深度优先搜索的特点是: (1)无论问题的内容和性质以及求解要求如何不同,它们的程序结构都是相同的,即都是深度优先算法(一)和深度优先算法(二)中描述的算法结构,不相同的仅仅是存储结点数据结构和产生规则以及输出要求. (2)深度优先搜索法有递归以及非递归两种设计方法.一般的,当搜索深度较小.问题递归方式比较明显时,用递归方法设计好,它可以使得程序结构更简捷易懂.当搜索深度较大时,当数据量较大时,由于系统堆栈容量的限制,递归容易产生溢出,用非递归方法设

创建二叉树 树的深度搜索 广度搜索

树的深度搜索 与树的前序遍历同理 根节点->左孩子->右孩子  树的广度搜索 与树的层次遍历同理 一层一层遍历内容 深度搜索 采用stack的适配器 先进后出原则  而广度搜索采用的queue适配器 先进先出原则 二者正好满足 搜索需求 简要代码如下: #include <iostream> #include <stack> #include <queue> #include <malloc.h> using namespace std; typ

图的深度及广度搜索

今天来学习下,图的遍历方法,我们以下面这个图为例. 开始之前呢,先说个题外话,我们用最常用的二维数组来存这个图,专业的叫法是邻接矩阵法,这好像不是题外话吧!!^_^要不要先自己想一下,上面这个图用邻接矩阵怎么存呢! 废话不多说,先来个深度的吧: 那什么叫深度搜索呢:以一个未访问过的顶点(图由顶点和边组成,不要说你不知道哦!)为起点,沿着当前顶点边走到未访问过的顶点,当没有未访问过的顶点时,回到该顶点的上一个顶点,继续走到其未访问过的顶点,直到所有顶点都被访问过.对文字不太感冒?来看下面的incl

基于C++ STL图的邻接表表示及深度、广度搜索实现

基于C++ STL图的邻接表表示及深度.广度搜索实现,对图论的学习有帮助,代码如下: #include <iostream> #include <vector> #include <set> using namespace std; #define MAX(a, b) ((a) > (b) ? (a) : (b) ) //定义图的定点 typedef struct Vertex { int id; vector<int> connectors; //存