Dfs/Bfs/记忆化搜索问题 | 问题集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dfs/Bfs/记忆化搜索问题 | 问题集合相关的知识,希望对你有一定的参考价值。

写在前面

动归和搜索似乎我打得特憋懒.

可能是因为搜索打的太少了???

然后之前做过的一些题我就不再写了,比如填涂颜色/海战啥的?

然后每一题打两种解法(:Dfs/Bfs

前提是在题目里两种都能A

 


 

 

P1596 湖计数

题目描述

Due to recent rains, water has pooled in various places in Farmer John‘s field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water (‘W‘) or dry land (‘.‘). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John‘s field, determine how many ponds he has.

由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水(‘W‘) 或是旱地(‘.‘)。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。

输入格式:

Line 1: Two space-separated integers: N and M * Lines 2..N+1: M characters per line representing one row of Farmer John‘s field. Each character is either ‘W‘ or ‘.‘. The characters do not have spaces between them.

第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是‘W‘或‘.‘,它们表示网格图中的一排。字符之间没有空格。

输出格式:

Line 1: The number of ponds in Farmer John‘s field.

一行:水坑的数量

输入输出样例

输入样例#1:
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出样例#1:
3

解题思路

    •   似乎之前我已经做过很多类似这种的题了??似乎类似于细胞问题?
    •        Dfs/Bfs都可以
    •        每次去找一个W,找到后往他的八连通方向找是否还存在W
    •        如果存在继续拓展,每次把找到的W改成.
    •        这样我们只需要找到一个W,就可以把与这个W八连通(或者说他存在的水坑)全部改成.
    •        最后只需要统计找到W的次数
    •        W出现的次数就是水坑的个数,输出即可.

关于代码

技术分享
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<cmath>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 
10 char Map[111][111];
11 
12 void Dfs(int i , int j){
13     if (Map[i][j] == 0)
14         return;
15     Map[i][j] = 0;
16     Dfs(i+1 , j);
17     Dfs(i-1 , j);
18     Dfs(i , j+1);
19     Dfs(i , j-1);
20     Dfs(i+1 , j+1);
21     Dfs(i+1 , j-1);
22     Dfs(i-1 , j+1);
23     Dfs(i-1 , j-1);
24 }
25 int main(){
26     
27     ios :: sync_with_stdio(0);
28     int n , m ;
29     char a;
30     cin >> n >> m;
31     for (int i = 1;i <= n;++i)
32         for (int j = 1;j <= m;++j){
33             cin >> a;
34             if (a == .) Map[i][j] = 0;
35                 else Map[i][j] = 1;
36         }
37     
38     int Ans_sum = 0;
39     for (int i = 1;i <= n;++i)
40         for (int j = 1;j <= m;++j){
41             if (Map[i][j] == 1)
42                 Ans_sum++;
43                 Dfs(i , j);
44             }
45             
46     cout << Ans_sum;
47 } 
湖计数/Dfs
技术分享
 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <queue>
 8 
 9 using namespace std;
10 
11 int Map[111][111];
12 int Book[111][111];
13 
14 queue <int> que;
15 
16 const int dx[8] = {0,0,1,-1,1,1,-1,-1},dy[8] = {1,-1,0,0,1,-1,1,-1}; 
17 
18 void Bfs(int x , int y){
19     Map[x][y] = 0;
20     Book[x][y] = 1;
21     que.push(x);
22     que.push(y);
23     int Ans_head , Ans_tail;
24     
25     while(!que.empty()){
26         Ans_head = que.front(),que.pop();
27         Ans_tail = que.front(),que.pop();
28         for (int i = 0;i < 8;++i){
29             int New_head = Ans_head+dx[i];
30             int New_tail = Ans_tail+dy[i];
31             if (Map[New_head][New_tail] && !Book[New_head][New_tail]){
32                 Map[New_head][New_tail] = 0;
33                 Book[New_head][New_tail] = 1;
34                 que.push(New_head);
35                 que.push(New_tail);
36             }
37         }
38     }
39 }
40 int main(){
41     
42     ios :: sync_with_stdio(0);
43     int n , m ;
44     char a;
45     cin >> n >> m;
46     for (int i = 1;i <= n;++i)
47         for (int j = 1;j <= m;++j){
48             cin >> a;
49             if (a == .) Map[i][j] = 0;
50                 else Map[i][j] = 1;
51         }
52     
53     int Ans_sum = 0;
54     for (int i = 1;i <= n;++i)
55         for (int j = 1;j <= m;++j)
56             if (Map[i][j] == 1){
57                 Ans_sum++;
58                 Bfs(i , j);
59         }
60 
61 
62     cout << Ans_sum;    
63 } 
湖计数/Bfs

 

 

 


 

P1657 选书

题目描述

学校放寒假时,信息学奥赛辅导老师有1,2,3……x本书,要分给参加培训的x个人,每人只能选一本书,但是每人有两本喜欢的书。老师事先让每个人将自己喜欢的书填写在一张表上。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意.

输入格式:

第1行:一个数x

第2行~第1+x行:每行两个数,表示ai喜欢的书的序号

输出格式:

只有一个数:总方案数total。

输入输出样例

输入样例#1:
5
1 3
4 5
2 5
1 4
3 5
输出样例#1:
2

解题思路

    •   生成全排列+可行性剪枝

  关于代码

技术分享
#include<iostream>
#include<cstdio>
using namespace std;

int ans,n,love1,love2,like[21][21];
int choose[21];

void dfs(int n,int k){
    for(int i = 1; i <= n;i++) {
        if(!choose[i] && like[k][i]) {
            choose[i] = 1;
            if(k == n) ans++;
            else dfs(n , k+1);
            choose[i] = 0;
        }
    }
}

int main() {
    
    ios :: sync_with_stdio(0);
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> love1 >> love2;
        like[i][love1] = 1;
        like[i][love2] = 1;
    }
    
    dfs(n,1);
    
    cout << ans << endl;
    return 0;
}
选书/Dfs

 





以上是关于Dfs/Bfs/记忆化搜索问题 | 问题集合的主要内容,如果未能解决你的问题,请参考以下文章

leetcode之最短路径+记忆化dfs+bfs+动态规划刷题总结

搜索分析(DFSBFS递归记忆化搜索)

P1044 栈 卡特兰数/记忆化搜索

图论:DFS,BFS,邻接链表,并查集

12.石油储备(DFS/BFS 统计连通块个数)

POJ 2243 简单搜索 (DFS BFS A*)