NYOJ—最少步数( 迷宫)
来源:互联网 发布:网络统考成绩查询2017 编辑:程序博客网 时间:2024/05/29 06:32
描述
这有一个迷宫,有0~8行和0~8列:
1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 1,0,0,1,1,0,0,0,1 1,0,1,0,1,1,0,1,1 1,0,0,0,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,1,0,0,1 1,1,0,1,0,0,0,0,1 1,1,1,1,1,1,1,1,1
0表示道路,1表示墙。
现在输入一个道路的坐标作为起点,再如输入一个道路的坐标作为终点,问最少走几步才能从起点到达终点?
(注:一步是指从一坐标点走到其上下左右相邻坐标点,如:从(3,1)到(4,1)。)
输入
第一行输入一个整数n(0 < n <=100),表示有n组测试数据;
随后n行,每行有四个整数a,b,c,d(0<=a,b,c,d<=8)分别表示起点的行、列,终点的行、列。
输出
输出最少走几步。
样例输入:
2
3 1 5 7
3 1 6 7
样例输出:
12
11
分析:
这个题目就是很寻常的BFS求最短路径问题。起点和终点用两个结点表示。
注意需要用vis保存已经走过的点的最短路径,如果不这样就会导致超时。
#include<cstdio>#include<queue>#include<cstring>using namespace std;struct Node{ int x,y; int dis; Node(int x=0,int y=0,int dis=0):x(x),y(y),dis(dis){}};const int a[9][9]={{1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,1,0,1}, {1,0,0,1,1,0,0,0,1}, {1,0,1,0,1,1,0,1,1}, {1,0,0,0,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1}};//迷宫 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int vis[9][9];Node begin,end; //起点和终点 int bfs(){ queue<Node> q; q.push(begin); memset(vis,0,sizeof(vis)); vis[begin.x][begin.y] = 1; while(!q.empty()) { Node v = q.front(); q.pop(); if(v.x == end.x && v.y == end.y) { return v.dis; break; } for(int i=0;i<4;i++) { int x = v.x + dir[i][0]; int y = v.y + dir[i][1]; if(x<0||x>=9||y<0||y>=9||a[x][y]) { continue; } if(!vis[x][y]&&!a[x][y]) { vis[x][y] = 1; Node k(x,y,v.dis+1); q.push(k); } } }}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d%d%d",&begin.x,&begin.y,&end.x,&end.y); begin.dis = 0; printf("%d\n",bfs()); } return 0;}
后来通过别人的思想发现此题也可以使用DFS来解决。
思想是通过DFS从起点到达终点,走过的步数取最小。
#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;const int map[9][9]={{1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,1,0,1}, {1,0,0,1,1,0,0,0,1}, {1,0,1,0,1,1,0,1,1}, {1,0,0,0,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,1,0,0,1}, {1,1,0,1,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1}};//迷宫 int x1,y1,x2,y2;int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};int vis[9][9]={0};int min = 99999;void dfs(int x,int y,int step){ if(x==x2&&y==y2) { if(step < min) { min = step;//取最小 return; } } for(int k = 0; k < 4; k++) { int nx = x + dir[k][0]; int ny = y + dir[k][1]; if(nx<0||nx>9||ny<0||ny>9) continue; if( map[nx][ny] == 0 && vis[nx][ny] == 0) { vis[nx][ny] = 1;//记录为已走过 dfs(nx,ny,step+1); vis[nx][ny] = 0;//注意要清除标志 } } return;}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); vis[x1][y1] = 1; dfs(x1,y1,0); printf("%d\n",min); } return 0;}
很经典的题,两种方法都需要非常熟悉。
0 0
- NYOJ—最少步数( 迷宫)
- NYOJ 最少步数
- nyoj 最少步数
- NYOJ【最少步数】
- nyoj 最少步数
- NYOJ-最少步数
- NYOJ 最少步数
- nyoj-最少步数
- NYOJ 最少步数
- NYOJ最少步数
- 最少步数(迷宫问题类型)
- 最少步数(NYOJ 58)
- nyoj 58 最少步数(BFS)
- nyoj-58 最少步数(DFS)
- NYOJ 58 最少步数(dfs)
- NYOJ 58 最少步数 (DFS)
- NYoj最少步数(DFS)
- nyoj 最少步数(BFS,DFS)
- CRC校验原理剖析
- netstat 的一些参数
- * 24种设计模式——单例模式
- HDU 5386 Cover
- 追梦
- NYOJ—最少步数( 迷宫)
- ubuntu16.10开启telnet办法
- Python第三方包OpenCV读取MP4格式文件的问题
- BZOJ 1691 [Usaco2007 Dec]挑剔的美食家
- linux errno查看和使用
- Shell学习
- 操作系统之汇编语言(1)
- 使用showMessageDialog显示消息框
- 微生物繁殖