题目1335:闯迷宫(40分)
题目描述:
sun所在学校每年都要举行电脑节,今年电脑节有一个新的趣味比赛项目叫做闯迷宫。
sun的室友在帮电脑节设计迷宫,所以室友就请sun帮忙计算下走出迷宫的最少步数。
知道了最少步数就可以辅助控制比赛难度以及去掉一些没有路径到达终点的map。
比赛规则是:从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走。
输入:
输入有多组数据。
每组数据输入n(0<n<=100),然后输入n*n的01矩阵,0代表该格子没有障碍,为1表示有障碍物。
注意:如果输入中的原点和终点为1则这个迷宫是不可达的。
输出:
对每组输入输出该迷宫的最短步数,若不能到达则输出-1。
样例输入:
2 0 1 0 0 5 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0
样例输出:
2 8
答疑:
解题遇到问题?分享解题心得?讨论本题请访问:http://t.jobdu.com/thread-8058-1-1.html
用DFS会时间超限,开始因为DFS比较熟练,就直接用了DFS,结果时间超限
题意就是上下左右走,然后判断是否到达(n-1,n-1)这点,记录下走了多少步就可以了,DFS是边走边判断是否当前为最小步数
BFS是步数小的先push进去,达到(n-1,n-1)就直接结束,后面的不会push进去了
理解一下bfs的实现:
当前点到起点的距离都是最小的
在队列里面不需要回溯,vis数组不需要重置,因为在当前点的情况下走不通了在另外的情况下依然不行
原来的DFS代码
#include<iostream> #include<cstdio> #include<cstring> #define maxn 105 using namespace std; int sum; int n; int vis[maxn][maxn],mapn[maxn][maxn]; void dfs(int a,int b,int step) { int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; if(a==n-1&&b==n-1) { if(sum>step) sum=step; return; } int x,y; for(int i=0;i<4;i++) { x=a+mov[i][0]; y=b+mov[i][1]; if(x<0||x>=n||y<0||y>=n) continue; if(mapn[x][y]==0&&vis[x][y]==0) { vis[x][y]=1; dfs(x,y,step+1); vis[x][y]=0; } } } int main() { while(cin >> n) { sum=1000; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin >> mapn[i][j]; if(mapn[0][0]==1||mapn[n-1][n-1]==1) { cout << "-1" << endl; continue; } memset(vis,0,sizeof(vis)); dfs(0,0,0); if(sum==1000) cout << "-1" << endl; else cout << sum << endl; } return 0; }
后面AC的BFS代码
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxn 105 using namespace std; int n; int dx[] = {-1,1,0,0}, dy[]= {0,0,-1,1}; int mapn[maxn][maxn]; struct node { int x,y,step; }; void bfs() { queue<node>q; struct node p; p.x=p.y=p.step=0; mapn[0][0]=1; q.push(p); while(!q.empty()) { struct node now = q.front(); q.pop(); int x = now.x,y = now.y; if(x==n-1&&y==n-1) { printf("%d\n",now.step); return; } for(int i=0;i<4;i++) { int xx = x+dx[i]; int yy = y+dy[i]; if(xx<0||xx>=n||yy<0||yy>=n||mapn[xx][yy]) continue; struct node tmp; tmp.x = xx; tmp.y = yy; tmp.step = now.step + 1; q.push(tmp); mapn[xx][yy] = 1; } } printf("-1\n"); } int main() { while(~scanf("%d",&n)) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) { scanf("%d",&mapn[i][j]); } if(mapn[0][0]||mapn[n-1][n-1]) { printf("-1\n"); continue; } bfs(); } return 0; }
- 上一篇 »贝壳2020——Java校招笔试题
- 下一篇 »Java日志记录log4j最简明教程