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.
一行:水坑的数量
输入输出样例
10 12 W........WW. .WWW.....WWW ....WW...WW. .........WW. .........W.. ..W......W.. .W.W.....WW. W.W.W.....W. .W.W......W. ..W.......W.
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 }
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 }
P1657 选书
题目描述
学校放寒假时,信息学奥赛辅导老师有1,2,3……x本书,要分给参加培训的x个人,每人只能选一本书,但是每人有两本喜欢的书。老师事先让每个人将自己喜欢的书填写在一张表上。然后根据他们填写的表来分配书本,希望设计一个程序帮助老师求出所有可能的分配方案,使每个学生都满意.
输入格式:
第1行:一个数x
第2行~第1+x行:每行两个数,表示ai喜欢的书的序号
输出格式:
只有一个数:总方案数total。
输入输出样例
5 1 3 4 5 2 5 1 4 3 5
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/Bfs/记忆化搜索问题 | 问题集合的主要内容,如果未能解决你的问题,请参考以下文章