NYOJ----最少步数
最少步数
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
-
这有一个迷宫,有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,10表示道路,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
用dfs 或 bfs进行穷举
(1)DFS1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495#include <stdio.h>
#include <string.h>
#define INF 80
int
res,flag[9][9];
int
maze[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
};
void
DFS(
int
si,
int
sj,
int
ei,
int
ej,
int
count){
if
(si==ei && sj==ej){
if
(count + 1 < res)
res = count+1;
return
;
}
if
(si<0 || si>8 || sj<0 || sj>8 || flag[si][sj] || maze[si][sj])
return
;
flag[si][sj]=1;
// four corners
if
((si==0 || si==8) && ((sj==0 || sj==8))){
int
ssi,sssi,ssj,sssj;
if
(si==0 && sj==0){
ssi=si+1,ssj=sj;
sssi=si,sssj=sj+1;
}
else
if
(si==0 && sj==8){
ssi=si+1,ssj=sj;
sssi=si-1,sssj=sj;
}
else
if
(si==8 && sj==0){
ssi=si-1,ssj=sj;
sssi=si,sssj=sj+1;
}
else
{
ssi=si-1,ssj=sj;
sssi=si,sssj=sj-1;
}
DFS(ssi,ssj,ei,ej,count+1);
DFS(sssi,sssj,ei,ej,count+1);
}
//four edges
else
if
(!(si>0 && si<8 && sj>0 && sj<8)){
int
ssi,ssj,sssi,sssj,ssssi,ssssj;
if
(si==0){
ssi=si,ssj=sj-1;
sssi=si,sssj=sj+1;
ssssi=si+1,ssssj=sj;
}
else
if
(si==8){
ssi=si,ssj=sj-1;
sssi=si,sssj=sj+1;
ssssi=si-1,ssssj=sj;
}
else
if
(sj==0){
ssi=si,ssj=sj+1;
sssi=si-1,sssj=sj;
ssssi=si+1,ssssj=sj;
}
else
{
ssi=si-1,ssj=sj;
sssi=si+1,sssj=sj;
ssssi=si,ssssj=sj-1;
}
DFS(ssi,ssj,ei,ej,count+1);
DFS(sssi,sssj,ei,ej,count+1);
DFS(ssssi,ssssj,ei,ej,count+1);
}
else
{
DFS(si-1,sj,ei,ej,count+1);
DFS(si+1,sj,ei,ej,count+1);
DFS(si,sj-1,ei,ej,count+1);
DFS(si,sj+1,ei,ej,count+1);
}
flag[si][sj]=0;
}
int
main(){
int
n,si,sj,ei,ej;
scanf(
"%d"
,&n);
while
(n--){
scanf(
"%d%d%d%d"
,&si,&sj,&ei,&ej);
res = INF;
memset(flag,0,
sizeof
(flag));
DFS(si,sj,ei,ej,-1);
printf(
"%d\n"
,res);
}
return
0;
}
(2)BFS
bfs求最小步数之所以不用更新距离d,是因为访问任何一个点(i,j)
必然都是距离(si,sj)最短距离(联想起bfs的分支图即明白这一点)123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#include <iostream>
#include <cstdio>
#include <queue>
using
namespace
std;
typedef pair<
int
,
int
> P;
//用结构体struct point{x,y}亦可
const
int
INF=80;
char
maze[10][10]={
//用char更节约内存
"111111111"
,
"100100101"
,
"100110001"
,
"101011011"
,
"100001001"
,
"110101001"
,
"110101001"
,
"110100001"
,
"111111111"
};
int
sx,sy,gx,gy;
int
d[9][9];
//出发点到(i,j)的最短路径,同时起到判断是否已访问的作用
int
dis[4][2]={
//or 定义dx[4]&dy[4]
1,0,
0,1,
-1,0,
0,-1
};
void
Init(){
int
i,j;
for
(i=0;i<9;i++)
for
(j=0;j<9;j++)
d[i][j]=INF;
}
void
BFS(){
queue <P> q;
q.push(P(sx,sy));
d[sx][sy]=0;
while
(q.size()){
//or !q.empty():仍有点未被访问
P p=q.front();
q.pop();
if
(p.first==gx && p.second==gy)
break
;
int
i=0;
for
(;i<4;i++){
int
x=p.first+dis[i][0],y=p.second+dis[i][1];
if
(x>=0 && x<=8 && y>=0 && y<=8
&& maze[x][y]==
'0'
&& d[x][y]==INF){
//表示(x,y)暂未访问
d[x][y]=d[p.first][p.second]+1;
q.push(P(x,y));
}
}
}
printf(
"%d\n"
,d[gx][gy]);
}
int
main(){
int
n;
scanf(
"%d"
,&n);
while
(n--){
scanf(
"%d%d%d%d"
,&sx,&sy,&gx,&gy);
Init();
BFS();
}
return
0;
}
对BFS的一点补充。。。
我们实际可以不用定义点,只要能够对不同的点进行区分即可,用9*i+j可将二维的点转化为一维(实际有点时间换空间的意味,全当另一种方法的了解),核心如下:
int graph[81],front,rear;front和rear共同起到队列的作用,入队,graph[rear++]=9*i+j(入队点为(i,j)),出队时,x=graph[front]/9,y=graph[front++]%9;
其余同BFS代码
其中,bfs的代码参照:http://blog.csdn.net/sevenmit/article/details/13168363
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· Ollama系列05:Ollama API 使用指南
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率
2016-03-04 Hanoi塔