没有学的太多,因为要赶图论和动规。
感觉到了dfs和bfs的不同:
1.dfs有一种一直往前冲,没路了再回头的感觉。而bfs的感觉就是把这一层的全搞完在进到下一层,举个例子,dfs融化冰的话就是直接打无数个洞。而bfs则是慢慢的一层一层融化。
2.bfs好像不是都需要递归来写的,有一些也是用循环来写的。但是我写过的所有dfs都是递归。
3.bfs的总是会需要一个队列和一个bool数组来维护。
4.似乎我写过的所有dfs都是求组合总类,bfs总是再找最优解。
5.dfs可以加记忆化来优化。而bfs的bool数组除了避免重复以外貌似让bfs的效率和dfs+记忆化的效率差不多。
有两道bfs的例题:
T1:
Farmer John为了满足宁智贤对美的享受而安装了人工湖。矩形的人工湖分成
M行N列(1 <= M <= 30; 1 <= N <= 30)的方形小格子。有些格子有美丽的荷
叶,有些有岩石,剩下的格子有的只是美丽的蓝色湖水。
宁智贤通过从一片荷叶跳到另一片荷叶上来练习芭蕾。它现在正站在一片荷叶
上(看输入数据了解具体位置)。它希望通过在荷叶上跳跃来到达另一片荷叶。
它既不能跳到水里也不能跳到岩石上。
只有新手才会感到吃惊:宁智贤的跳跃有点类似国际象棋中马那样的移动,在一
个方向上(如水平方向)移动M1(1 <= M1 <= 30)“格”,然后再在另一个方向上(如竖直方向)移动M2 (1 <= M2 <= 30; M1 != M2)格,所以宁智贤有时可能有多达8中的跳跃选择。
给出池塘的构造以及宁智贤跳跃的形式,找出宁智贤从一个位置移动到另一个位置
所需的最小的跳跃次数。这个跳跃对于所给的测试数据总是可能的。
输入格式:
* 第 1 行: 四个空格分开的整数: M, N, M1, 和 M2
* 第 2 至 M+1行: 第i+1行用N个空格分开的整数描述池塘第i行,0表示水,1表示荷叶,2表示岩石,3表示宁智贤现在站的那块荷叶,4表示跳跃的终点。
输出格式:
一个整数,是宁智贤从一块荷叶跳到另一块荷叶所需的最小的跳跃数。
样例输入:
4 5 1 2
1 0 1 0 1
3 0 2 0 4
0 1 2 0 0
0 0 0 1 0
样例输出:
2
#include<iostream> #include<cstdio> #include<algorithm> #include<ctime> #include<cmath> #include<cstring> using namespace std; struct hehe { int x,y; int ans; }; hehe q[1000100]; int head=0,tail=0; int m,n,m1,m2; bool vis[50][50]; int main() { //freopen("add.in","r",stdin); //freopen("add.out","w",stdout); memset(vis,0,sizeof(vis)); memset(q,0,sizeof(q)); cin>>m>>n>>m1>>m2; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { int r; cin>>r; if(r==0 || r==2) vis[i][j]=1; if(r==3) q[++tail].x=i,q[tail].y=j,q[tail].ans=0,vis[i][j]=1; if(r==4) q[0].x=i,q[0].y=j; } } /*for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) cout<<vis[i][j]<<' '; cout<<endl; }*/ int dx[8]={m1,m1,-m1,-m1,m2,m2,-m2,-m2},dy[8]={m2,-m2,m2,-m2,m1,-m1,m1,-m1}; int k=0; for(int i=1;i<=tail;i++) { for(int j=0;j<8;j++) { int xx=q[i].x+dx[j]; int yy=q[i].y+dy[j]; if(xx<=0 || xx>m || yy<=0 || yy>n) continue; if(xx==q[0].x && yy==q[0].y){cout<<q[i].ans+1<<endl;return 0;} if(!vis[xx][yy]) { q[++tail].x=xx;q[tail].y=yy;q[tail].ans=q[i].ans+1; vis[xx][yy]=1; } } } cout<<q[k].ans+1<<endl; //fclose(stdin);fclose(stdout); return 0; }
有一个小技巧,这种二维数组的问题很多时候开一个方向数组比自己手动敲好多情况要方便>_<!
bfs 的时候要注意边界。
当head>tail的时候就证明你已经把所有情况都试过了,但是仍然不能完成题目的要求(这道题保证了有解)。
另外,个人感觉bfs比dfs好一点,不知道为什么。