Description
Alice住在森林里,森林可以看作是N*M的网格,森林里有怪兽,用‘.’表示空地,‘+’表示怪兽,‘V’表示Alice现在的位置,‘J’表示Alice的家。
Alice可以从当前单元格向上下左右相邻单元格移动,有怪兽的地方也可以走,只不过比较危险,有怪兽的单元格对其他单元格会产生一定的危险系数,假设怪兽位置为(A,B),它对某单元格(R,C)的危险系数为:|R-A|+|C-B|,危险系数越小越危险,每个单元格的危险系数是所有怪兽对它产生的系数的最小值。
Alice请你帮她找一条最佳路径回家,即使得路径上经过单元格的最小的危险系数最大。
Input
输入第一行包含两个整数N和M(1<=N,M<=500),表示森林的大小。
接下来N行每行包含M个字符:‘.’,‘+’,‘V’,‘J’。
输入只包含一个‘V’和‘J’,而且至少有一个‘+’。
Output
输出最佳路径中最小的危险系数。
题解
这种题目A了才有成就感呀
对于每个怪兽,我们做一次bfs求出每个点的危险系数,然后二分可能的最小危险系数值,代进bfs判断是否可行
交了很多次发现原来是万恶的ansistring在捣鬼,默默吐槽然后就过了
还有就是要判断起点是否大于我们二分的最小值,这点很坑
优化:经过哲♂学地判断我们发现最大值不会超过50 (别问我为什么)
code
type
state=record
x,y:longint;
end;
const
dx:array[1..4]of integer=(-1,1,0,0);
dy:array[1..4]of integer=(0,0,-1,1);
var
n,m:longint;
map:array[0..501,0..501]of longint;
f:array[0..501,0..501]of boolean;
s:array[1..251000]of state;
st,ed:state;
function bfs(w:longint):boolean;
var
i,x,y,head,tail:longint;
begin
if map[st.x,st.y]<w then exit(false);
fillchar(s,sizeof(s),0);
fillchar(f,sizeof(f),false);
bfs:=false;
head:=0;
tail:=1;
s[1].x:=st.x;
s[1].y:=st.y;
repeat
inc(head);
if (s[head].x=ed.x)and(s[head].y=ed.y) then exit(true);
for i:=1 to 4 do
begin
x:=s[head].x+dx[i];
y:=s[head].y+dy[i];
if (not f[x,y])and(map[x,y]>=w)and(x>0)and(x<=n)and(y>0)and(y<=m) then
begin
inc(tail);
f[x,y]:=true;
s[tail].x:=x;
s[tail].y:=y;
end;
end;
until head>=tail;
end;
procedure main;
var
l,r,mid,ans:Longint;
b:boolean;
begin
l:=0;
r:=50;
ans:=0;
while l<=r do
begin
mid:=(l+r)shr 1;
b:=bfs(mid);
if b then
begin
if mid>ans then ans:=mid;
l:=mid+1;
end
else
r:=mid-1;
end;
writeln(ans);
end;
procedure init;
var
i,j,head,tail,x,y,z:longint;
sr:ansistring;
begin
fillchar(s,sizeof(s),0);
fillchar(map,sizeof(map),$7f div 2);
tail:=0;
head:=0;
readln(n,m);
for i:=1 to n do
begin
readln(sr);
for j:=1 to m do
begin
case sr[j] of
'J':
begin
ed.x:=i;
ed.y:=j;
end;
'V':
begin
st.x:=i;
st.y:=j;
end;
'+':
begin
inc(tail);
s[tail].x:=i;
s[tail].y:=j;
map[i,j]:=0;
end;
end;
end;
end;
repeat
inc(head);
for i:=1 to 4 do
begin
x:=s[head].x+dx[i];
y:=s[head].y+dy[i];
z:=map[s[head].x,s[head].y]+1;
if (map[x,y]>z)and(x>0)and(x<=n)and(y>0)and(y<=m) then
begin
inc(tail);
s[tail].x:=x;
s[tail].y:=y;
map[x,y]:=map[s[head].x,s[head].y]+1;
end;
end;
until head>=tail;
end;
begin
init;
main;
end.