java武士风度_tyvj p1074 武士风度的牛(比较经典的BFS)

这篇博客介绍了如何解决一个关于骑士在棋盘上寻找最短路径到达草地的问题,采用广度优先搜索(BFS)算法,通过一个简单的先进先出队列来寻找从起点到草地的最少跳跃次数。给出了样例输入和输出,以及具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景 Background

农民John有很多牛,他想交易其中一头被Don称为The Knight的牛。这头牛有一个独一无二的超能力,在农场里像Knight一样地跳(就是我们熟悉的象棋中马的走法)。虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个x,y的坐标图来表示。

描述 Description

这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了The Knight的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。现在你的任务是,确定The Knight要想吃到草,至少需要跳多少次。The Knight的位置用'K'来标记,障碍的位置用'*'来标记,草的位置用'H'来标记。

这里有一个地图的例子:(图贴过来有点乱,还是去看原题吧)

11 | . . . . . . . . . .

10 | . . . . * . . . . .

9 | . . . . . . . . . .

8 | . . . * . * . . . .

7 | . . . . . . . * . .

6 | . . * . . * . . . H

5 | * . . . . . . . . .

4 | . . . * . . . * . .

3 | . K . . . . . . . .

2 | . . . * . . . . . *

1 | . . * . . . . * . .

0 ----------------------

1

0 1 2 3 4 5 6 7 8 9 0

The Knight 可以按照下图中的A,B,C,D...这条路径用5次跳到草的地方(有可能其它路线的长度也是5):

11 | . . . . . . . . . .

10 | . . . . * . . . . .

9 | . . . . . . . . . .

8 | . . . * . * . . . .

7 | . . . . . . . * . .

6 | . . * . . * . . . F<

5 | * . B . . . . . . .

4 | . . . * C . . * E .

3 | .>A . . . . D . . .

2 | . . . * . . . . . *

1 | . . * . . . . * . .

0 ----------------------

1

0 1 2 3 4 5 6 7 8 9 0

输入格式 Input Format

第一行: 两个数,表示农场的列数和行数

第二行..结尾: 如题目描述的图。

输出格式 Output Format

一个数,表示跳跃的最小次数。

样例输入 Sample Input

10 11

..........

....*.....

..........

...*.*....

.......*..

..*..*...H

*.........

...*...*..

.K........

...*.....*

..*....*..

样例输出 Sample Output

5

时间限制 Time Limitation

1s

注释 Hint

Hint:这类问题可以用一个简单的先进先出表(队列)来解决。

来源 Source

usaco nov09 Cu

翻译by pricez

题目分析:在本题的注释中已经告诉我们,这道题是需要用宽搜的,而且据说宽搜求最小步数问题很给力……所以……我就宽搜了

代码:

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.png代码program p1074;

const dx:array[1..8]of -2..2=(-2,-1,1,2,-2,-1,1,2);

dy:array[1..8]of -2..2=(1,2,2,1,-1,-2,-2,-1);

var a:array[-100..200,-100..200]of char;

f:array[-100..200,-100..200]of longint;

qx,qy:array[1..10000]of longint;

vis:array[-100..200,-100..200]of boolean;

n,m,x0,y0,x,y,x1,y1,head,tail:longint;

procedure init;

var i,j:longint;

begin

assign(input,'input.txt');

reset(input);

assign(output,'output.txt');

rewrite(output);

readln(m,n);

for i:=1 to n do

begin

for j:=1 to m do

begin

read(a[i,j]);

if a[i,j]='K' then

begin

x0:=i;

y0:=j;

end

else

if a[i,j]='H' then

begin

x:=i;

y:=j;

end;

vis[i,j]:=false;

end;

readln;

end;

close(input);

end;

procedure main;

var i:longint;

begin

head:=1;

tail:=1;

qx[1]:=x0;

qy[1]:=y0;

vis[x0,y0]:=true;

while head<=tail do

begin

x1:=qx[head];

y1:=qy[head];

for i:=1 to 8 do

if (not vis[x1+dx[i],y1+dy[i]])and((a[x1+dx[i],y1+dy[i]]='.')or(a[x1+dx[i],y1+dy[i]]='H'))then

begin

f[x1+dx[i],y1+dy[i]]:=f[x1,y1]+1;

inc(tail);

qx[tail]:=x1+dx[i];

qy[tail]:=y1+dy[i];

vis[x1+dx[i],y1+dy[i]]:=true;

if (x1+dx[i]=x)and(y1+dy[i]=y) then

begin

writeln(f[x1+dx[i],y1+dy[i]]);

halt;

end;

end;

inc(head);

end;

end;

begin

init;

main;

close(output);

end.

---------------------------------由JackerJay原创,转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值