noj:广搜 (bfs) and 深搜(dfs) 整理
来源:互联网 发布:弘付数据科技有限公司 编辑:程序博客网 时间:2024/05/16 06:08
一、DFS
1.迷宫问题
Description
Input
迷宫使用0和1字符表示,0表示有路1表示为墙.迷宫为正方形.左上角为(1,1),右下角为(N,N).左上角为入口,出口在(N,N).
输入第一行有3个正整数N,x,y.
N表示迷宫规模,x,y表示Jack和同学所在的迷宫位置. 要求找出从(x,y)到(N,N)的路径( N ≤ 80 ). 且出口和入口的值一定为0
下边为迷宫的字符模型用01表示.
Output
假如未找到输出Not Found
Sample Input
6 5 20 0 1 1 1 11 0 0 0 0 11 1 1 0 1 11 0 0 0 1 11 0 1 0 1 11 0 1 0 0 0
Sample Output
Found0 0 1 1 1 11 0 0 # # 11 1 1 # 1 11 0 0 # 1 11 0 1 # 1 11 0 1 # # #
Hint
Source
noj.io 1010
solution:
#include<stdio.h>const int M=81;int maze[M][M],n;int dir[][2]={{0,1},{1,0},{0,-1},{-1,0}};bool dfs(int x,int y){ maze[x][y]=-1; for(int i=0; i<4; ++i) { int nextx=x+dir[i][0]; int nexty=y+dir[i][1]; if(nextx==n && nexty==n) { maze[nextx][nexty]=-1; return 1; } else if(nextx==0||nextx==n+1||nexty==0||nexty==n+1||maze[nextx][nexty]!=0) continue; else if(dfs(nextx,nexty)) { maze[nextx][nexty]=-1; return 1; } } maze[x][y]=0; return 0;}int main(){ int x,y,i,j; while(scanf("%d %d %d",&n,&y,&x)!=EOF) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) scanf("%d",&maze[i][j]); if(dfs(x,y)) { printf("Found\n"); for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { if(maze[i][j]==-1) printf("# "); else printf("%d ",maze[i][j]); } printf("\n"); } } else printf("Not Found\n"); } return 0;}
给大一同学讲题的时候这题当场没写出来。。。
重写了一遍,感觉当时没有体会到回溯上一行return的意义,把dfs彻底当成brutal了。
代码:
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>using namespace std;char g[100][100];int dir[][4] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};int n;bool dfs(int x, int y){ if (x == n && y == n) return true; for (int i = 0; i < 4; i++) { int nx = x + dir[i][0]; int ny = y + dir[i][1]; if (1 <= nx && nx <= n && 1 <= ny && ny <= n && g[nx][ny] == '0') { g[nx][ny] = '#'; if (dfs(nx, ny)) return true; g[nx][ny] = '0'; } } return false;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL int x, y; while (scanf("%d%d%d", &n, &y, &x) == 3) { getchar(); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { scanf("%c", &g[i][j]); getchar(); } } g[x][y] = '#'; if (dfs(x, y)) { printf("Found\n"); for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%c ", g[i][j]); } printf("\n"); } } else printf("Not Found\n"); } return 0;}
2.图的连通性问题
(1).找油田
Description
Input
Output
Sample Input
1 1*3 5*@*@***@***@*@*1 8@@****@*5 5****@*@@*@*@**@@@@*@@@**@0 0
Sample Output
0122
Source
noj.io 1397
solution:
这题让我真正见识到dfs的魅力所在,解决连通性的利刃。
#include<stdio.h>const int N=101;int dir[][2]= {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};char oil[N][N];int m,n;void dfs(int x,int y){ if(oil[x][y]!='@'||x==0||y==0||x==m+1||y==n+1) return; else { oil[x][y]='0'; for(int i=0; i<8; i++) { dfs(x+dir[i][0],y+dir[i][1]); } }}int main(){ int i,j; while(scanf("%d%d",&m,&n)!=EOF) { int s=0; if(m==0&&n==0) break; getchar(); for(i=1; i<=m; i++) { for(j=1; j<=n; j++) { scanf("%c",&oil[i][j]); } getchar(); } for(i=1; i<=m; i++) { for(j=1; j<=n; j++) { if(oil[i][j]=='@') { dfs(i,j); s++; } } } printf("%d\n",s); } return 0; }
(2).找水洼
Description
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.Input
Output
Sample Input
10 12W........WW..WWW.....WWW....WW...WW..........WW..........W....W......W...W.W.....WW.W.W.W.....W..W.W......W...W.......W.
Sample Output
3
Hint
Source
noj.io 1158
solution:
同上题思路,稍微修改一下就好了,帅炸了!!
#include<stdio.h>const int N=101;int m,n;char lake[N][N];int dir[][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};void dfs(int x,int y){ if(lake[x][y]!='W'||x==0||y==0||x==m+1||y==n+1) return; else { lake[x][y]='0'; for(int i=0; i<8; i++) { dfs(x+dir[i][0],y+dir[i][1]); } }}int main(){ int i,j; while(scanf("%d%d",&m,&n)!=EOF) { int s=0; getchar(); for(i=1; i<=m; i++) { for(j=1; j<=n; j++) { scanf("%c",&lake[i][j]); } getchar(); } for(i=1; i<=m; i++) { for(j=1; j<=n; j++) { if(lake[i][j]=='W') { dfs(i,j); s++; } } } printf("%d\n",s); } return 0;}
1.类迷宫
Description
keefo 正在一个迷宫里找宝藏. keefo好不容易找到这个迷宫,这个迷宫传说中藏了不少的宝藏,当然他希望这次能够找出所所有的宝藏. 现在,他已经从杨过那里获得宝藏地图, 现在 keefo 想知道他能够获得多少宝藏.keefo 希望你能够帮他解决这个问题(呵呵~,不是白干哦, keefo会付给你酬金).
现在假设,迷宫是由正方形网格组成 . keefo在迷宫中,只能从 上 ,下,左,右四个方向移动. 但是如果他要走的前方是一堵墙的话,他将不能走过去. 并且,迷宫的四周都是由一堵厚实的墙包围着, 也就是说,keefo不可能走出迷宫之外.
Input
输入包含多组测试数据.
每组测试数据第一行包含两个整形数字, N 和 M ( 1 < N,M ≤ 1000 ), 分别表示迷宫网格的行和列.接下来N行里,每行包含了M个字符.( ´X´ 代表 keefo 当前位置 , ´*´ 代表宝藏 , ´#´代表墙, ´.´ 代表没有任何障碍 ).每个测试数据只包含一个 ´X´ 字符.
Output
输出keefo 能够找到的最多宝藏的个数.
每组数据一行.
Sample Input
4 4*....X.........*4 4*#..#X.........*
Sample Output
21
Source
noj.io 1215
solution:
#include<stdio.h>#include<string.h>#include<queue>using namespace std;const int N=1001;char maze[N][N];int n,m;int dir[][2]= {{0,1},{1,0},{0,-1},{-1,0}};bool visit[N][N]= {0};struct point{ int x,y;};int bfs(int x,int y){ int s=0; memset(visit,0,sizeof(visit)); queue<point> Q; point now,next; now.x=x; now.y=y; Q.push(now); visit[now.x][now.y] = 1; while(!Q.empty()) { now=Q.front(); Q.pop(); for(int i=0; i<4; i++) { next.x=now.x+dir[i][0]; next.y=now.y+dir[i][1]; if(next.x==0||next.y==0||next.x==n+1||next.y==m+1||visit[next.x][next.y]) continue; if(visit[next.x][next.y]==0) { if(maze[next.x][next.y]=='*') { s++; visit[next.x][next.y]=1; Q.push(next); } else if(maze[next.x][next.y]=='.') { visit[next.x][next.y]=1; Q.push(next); } else { continue; } } } } return s;}int main(){ int i,j,x,y; while(scanf("%d %d",&n,&m)!=EOF) { getchar(); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%c",&maze[i][j]); if(maze[i][j]=='X') { x=i; y=j; } } getchar(); } printf("%d\n",bfs(x,y)); } return 0;}
2.寻找最短路 and 3D迷宫
Description
你被关进了一个3D的地牢中,现在你需要找到最快的方法迅速的跑出监狱。 地牢是由每一个小方格组成,这些方格可能是墙壁。 假设你每移动一个单位(移动方向,可以是 东, 南, 西 ,北, 上, 下 )需要一分钟的时间。 你不能够沿对角线移动,并且不能够越过地牢,因为地牢四周被坚固的石头包围着。
你能够顺利的从这个地牢中逃脱吗? 你最少需要花多少时间呢?
Input
输入有多组测试数据。
每一个测试数据第一行有三个整形数据 L R 和 C ( L , R, C ≤ 30 )
L 表示地牢的层数 。
R 和 C 分别表示地牢每层的 行数 和 列数 。
接下来的L个地图分别表示地牢的每层地图,每个地图有R行,每行包括C个字符。 每个字符描绘着地牢的每一个小方格,´#´表示墙壁,你不能通过。´.´表示通道 。 并且你的起始地点 和终止分别是 ´S´ 和´E´.
每个地图之间间隔一行。
当L , R , C 均 为 0 时 ,表示输入结束。
Output
每一个测试数据占一行。
如果你能顺利的逃脱,那么请输出:
Escaped in x minute(s).
其中 x 表示 你逃脱所花的最短时间。
如果你不能顺利逃脱,那么请输出:
Trapped!
Sample Input
3 4 5S.....###..##..###.#############.####...###########.#######E1 3 3S###E####0 0 0
Sample Output
Escaped in 11 minute(s).Trapped!
Source
noj.io 1218
solution:
bfs常用来找最短路,不是证明过算导的最短路吗摔,怎么会不记得,第一次用了dfs 。。。wa了摔!!!
而所谓的3D迷宫,无非就是在平面x,y上再立一个z轴,不能斜着走的情况下只有6个方向。
代码:
#include<stdio.h>#include<string.h>#include<queue>using namespace std;char maze[31][31][31];int L,R,C;int xe,ye,ze;int dir[][3]= {{-1,0,0},{1,0,0},{0,0,1},{0,1,0},{0,0,-1},{0,-1,0}};bool vis[31][31][31]= {0};struct point{ int x,y,z; int num;};bool flag;int bfs(int z,int x,int y){ memset(vis,0,sizeof(vis)); queue<point> Q; point now,next; now.z=z; now.x=x; now.y=y; now.num=0; Q.push(now); while(!Q.empty()) { now=Q.front(); Q.pop(); vis[now.z][now.x][now.y]=1; for(int i=0; i<6; i++) { next.z=now.z+dir[i][0]; next.x=now.x+dir[i][1]; next.y=now.y+dir[i][2]; if(vis[next.z][next.x][next.y]||next.z==0||next.y==0||next.x==0||next.z==L+1||next.x==R+1||next.y==C+1||maze[next.z][next.x][next.y]=='#') continue; if(next.z==ze&&next.x==xe&&next.y==ye) { flag=1; next.num=now.num+1; return next.num; } else if(maze[next.z][next.x][next.y]=='.') { next.num=now.num+1; vis[next.z][next.x][next.y]=1; Q.push(next); } } }}int main(){ int i,j,k,xb,yb,zb,time; bool flag1,flag2; while(scanf("%d%d%d",&L,&R,&C)!=EOF) { getchar(); if(L==0&&R==0&&C==0) break; flag1=0; flag2=0; for(i=1; i<=L; i++) { for(j=1; j<=R; j++) { for(k=1; k<=C; k++) { scanf("%c",&maze[i][j][k]); if(!flag1||!flag2) { if(maze[i][j][k]=='S') { flag1=1; zb=i; xb=j; yb=k; } if(maze[i][j][k]=='E') { flag2=1; ze=i; xe=j; ye=k; } } } getchar(); } if(i<L) getchar(); } flag=0; time=bfs(zb,xb,yb); if(flag) printf("Escaped in %d minute(s).\n",time); else printf("Trapped!\n"); } return 0;}
- noj:广搜 (bfs) and 深搜(dfs) 整理
- 究竟应该采用“深搜”(DFS)还是“广搜”(BFS)?
- 图的遍历 (深搜DFS与广搜BFS)
- 深搜(DFS)VS 广搜(BFS)
- 图的遍历-深搜(DFS)和广搜(BFS)
- NYOJ58 最少步数(深搜DFS+广搜BFS+剪枝)
- HDU1372 Knight Moves(广搜BFS+深搜DFS)
- codevs 1215 迷宫 广搜bfs 深搜dfs
- 算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS
- POJ3984 迷宫问题(深搜DFS+广搜BFS)搜索记录坐标,坑
- 算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS
- 深搜和广搜 (DFS & BFS)
- hdu1312 Red and Black_广搜 dfs(java版本)
- 图的基本操作(基于邻接矩阵):图的构造,深搜(DFS),广搜(BFS)
- 图的基本操作(基于邻接表):图的构造,深搜(DFS),广搜(BFS)
- 图的基本操作(基于邻接表):图的构造,深搜(DFS),广搜(BFS)
- 图的基本操作(基于邻接矩阵):图的构造,深搜(DFS),广搜(BFS)
- 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS
- oracle之触发器
- 【PYC#1 欢乐赛】 题解
- 黑马程序员技术博客之集合框架总结
- 真正去掉EXCEL里的小数点
- 怒江豆腐干回复回复过
- noj:广搜 (bfs) and 深搜(dfs) 整理
- check 函数有关的流程图
- hdu1847Good Luck in CET-4 Everybody! (博弈)
- 黑马程序员---基础强化---封装的作用
- Spring源码学习 ------ IoC——AOP
- android,广播接收者,实现IP拨号
- 网络爬虫知多少
- Android中Gravity中的一些值都是些什么意思
- SPOJ Free tour II 点分治