<span style="font-size:18px;">题目大意</span>
有一个100*100的正方形湖,湖中间有一个直径为15的圆形小岛;
有n个点随机分布在这个正方形中;
一个人要从小岛上跳出湖外,可以跳跃在这些点上;
人每一步能跳的最大距离为d;
求能跳出湖外所需的最小的跳跃距离和步数;
分析
首先计算每个坐标两两间的距离;
然后找出所有能从小岛上一步跳到的点存入数组s中;
然后找出所有能一步跳出湖外的点存入数组t中;
设置两个虚拟的顶点s和t;
用s与数组s中的所有顶点相连;
用t与数组t中的所有顶点相连;
即此题可以转换成求s到t的最短路径;
注意
在建图的过程中,如果两个顶点之间的距离大于d了;
即两个顶点之间无法一步到达,所以此时将权值赋为无穷大;
此题很是有点卡精度,下面的pascal始终过不了。
代码
const
eps=1e-4;
var
f:array[1..200,1..200] of double;
a:array[1..200,1..2] of longint;
v,c:array[0..200] of longint;
d:array[0..200] of double;
i,j,l:longint;
x,y:longint;
x1,y1,k,q:double;
n,m:longint;
ans,max:longint;
procedure a1;
var
i,j:longint;
begin
for i:=1 to 200 do
for j:=1 to 200 do
f[i,j]:=maxlongint;
for i:=0 to 200 do
d[i]:=maxlongint;
end;
begin
while not eof do
begin
readln(n,q);
a1;
fillchar(a,sizeof(a),0);
fillchar(v,sizeof(v),0);
fillchar(c,sizeof(c),0);
y1:=d[1];
j:=0;
for i:=1 to n do
begin
readln(x,y);
if sqrt(sqr(x)+sqr(y))-7.5<=eps
then
continue;
j:=j+1;
a[j,1]:=x; a[j,2]:=y;
end;
n:=j;
if q-42.50>=eps
then
begin
writeln(42.5:0:2,' ',1);
continue;
end;
for i:=1 to n do
for j:=1 to n do
begin
f[i,j]:=sqrt(sqr(a[i,1]-a[j,1])+sqr(a[i,2]-a[j,2]));
if f[i,j]-q>eps
then
f[i,j]:=maxlongint;
end;
for i:=1 to n do
begin
x1:=sqrt(sqr(a[i,1])+sqr(a[i,2]))-7.5;
if x1-q>eps
then f[i,n+1]:=maxlongint
else f[i,n+1]:=x1;
f[n+1,i]:=f[i,n+1];
if abs(50-a[i,1])>abs(50-a[i,2])
then f[i,n+2]:=abs(50-a[i,2])
else f[i,n+2]:=abs(50-a[i,1]);
if f[i,n+2]-q>eps
then f[i,n+2]:=maxlongint;
f[n+2,i]:=f[i,n+2];
end;
n:=n+2;
d[n-1]:=0;
c[n-1]:=0;
for i:=1 to n do
begin
k:=maxlongint;
l:=0;
for j:=1 to n do
if (v[j]=0) and (d[j]-k<eps)
then
begin
k:=d[j];
l:=j;
end;
v[l]:=1;
if l=0 then break;
for j:=1 to n do
if (d[j]-d[l]-f[l,j]>eps) or ((d[j]-d[l]-f[l,j]<=eps) and (c[l]+1<c[j]))
then
begin
d[j]:=d[l]+f[l,j];
c[j]:=c[l]+1;
end;
end;
if d[n]=y1 then writeln('can''t be saved')
else writeln(d[n]:0:2,' ',c[n]);
end;
end.