2017.4.17 JZOJ渡河

Description

  传说中教主乃世外高人,不屑于参加OI竞赛,于是云游四方,威风八面。只不过教主行踪不定,就像传说中的神兽一样可遇而不可求。小L和小H为了求得教主签名的Orz教主T-Shirt,打算碰碰运气展开了冒险。在冒险中,他们不幸被突来的洪水冲到了一个神秘丛林中,他们想尽快逃出这个地方。小L找到了一张看似为曾经的冒险者遗弃的地图,但经过探查,地图所示的确实是这片丛林。小L从地图上看到,有众多河流穿过这片丛林,等到他接近一条最近的河流时,发现水流较急,且河水很深,小H不擅长游泳,所以他们决定利用丛林中的树木做一只竹筏渡河。
  虽然竹筏做好后可以在这一条河所连通的水域任意行进,但是竹筏在上岸后必须抛弃,若想再次渡河必须再做一次竹筏,但这毕竟是十分辛苦的,他们希望做竹筏也就是渡河的次数尽量少,就求助于你。
  地图上的陆地和河流可以抽象冲一个n*n由数字0和1组成的矩阵,其中0代表陆地,1代表河流。无论在陆地上还还是河流上,他们都可以向相邻8格(边相邻或角相邻)移动,但是若要从陆地进入河流(也就是从0到1),则必须制作竹筏。若到达地图边界则顺利逃脱。但是小T和小K有可能迷路,所以会多次询问你,对于每次询问,只要输出到达地图边界需要的最少渡河次数即可,保证每次询问都是指向陆地。
  小L和小H翻到地图的反面,赫然发现六个大字:“教主到此一游”!两人无法抑制自己激动的心情,将这张地图珍藏起来。据说后来这张图成为无价之宝。

Input

  第1行包括2个正整数N,K,分别描述了地图的长宽以及询问的次数。
  下面N行,每行N个数字0或者1,数字之间没有空格,描述了这张地图。
  接下来K行,每行2个正整数xi,yi,询问在第xi行第yi列最少需要渡河几次。

Output

  输出仅包括1行,按输入顺序每行对于一个询问输出最少需要渡河的次数,数字间用空格隔开,行末换行并没有空格。

正解:这一题是分层的bfs。
有一个重要的地方是要在四周围上陆地,使外层的陆地全部相连,然后往里面搜,
开两个数组:d数组表示这一次所经过的同类型地,
d1数组表示遇到的不同类型的地。

uses math;
var
i,j,k,n,m,p,q,x,y,ans:longint;
b,c:array[-1..1001,-1..1001]of longint;
a:array[-1..1001,-1..1001]of char;
bz:array[-1..1001,-1..1001]of boolean;
d,d1:array[1..1000000,1..3]of longint;
fx:array[1..8,1..2]of longint=((0,1),(1,0),(0,-1),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1));
procedure go;
var
i,j,k,x,y,w,t,w1,t1:longint;
begin
d[1,1]:=0;
d[1,2]:=0;
w1:=1;
k:=0;
t1:=2;
while w1<>0 do
begin
//fillchar(d1,sizeof(d1),0);
t:=1;
w:=w1;
w1:=0;
while t<=w do
begin
for i:=1 to 8 do
begin
x:=d[t,1]+fx[i,1];
y:=d[t,2]+fx[i,2];
if (x>-1) and (y>-1) and (x<=n+1) and (y<=n+1) and (bz[x,y]=false)then
begin
if (a[x,y]=a[d[1,1],d[1,2]]) then
begin
inc(w);
d[w,1]:=x;
d[w,2]:=y;
bz[x,y]:=true;
c[x,y]:=t1;
end
else
begin
inc(w1);
d1[w1,1]:=x;
d1[w1,2]:=y;
bz[x,y]:=true;
c[x,y]:=t1+1;
end;
end;
end;
inc(t);
end;
d:=d1;
inc(t1);
end;
end;
begin
assign(input,’b.in’); reset(input);
assign(output,’b.out’); rewrite(output);
readln(n,m);
for i:=1 to n do
begin
for j:=1 to n do
begin
reaD(a[i,j]);
end;
readln;
end;
for i:=0 to n+1 do
begin
a[0,i]:=’0’;
a[i,0]:=’0’;
a[n+1,i]:=’0’;
a[i,n+1]:=’0’;
end;
go;
for i:=1 to m do
begin
reaD(x,y);
write(c[x,y] div 2-1,’ ‘);
//write(b[x,y],’ ‘);
end;
close(input); close(output);
end.
sorry,本人还是P党,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值