矩阵中找一点使该点到各已知陷阱中最近的最远。
如果是神牛,自然可以用voronoi图
但是,由于较优值比较离散,所以编程复杂度较低,但期望得分较高的模拟退火显然更适用。
算法流程(转载)
p,l一开始我取的100,tle了,后来看别人取得20、25才改小的。
根据程序不同,要适当调整退火程度和下界
跑得很慢,该算法需要rp啊
const maxp=30;
maxt=0.2;
maxl=30;
var f,x,y,xx,yy:array[1..1000]of real;
n,p,i:longint;
ansx,ansy,ans,t:real;
maxx,maxy:longint;
function dist(x,y,z,p:real):real;
begin
exit(sqr(x-z)+sqr(y-p))
end;
function test(xx,yy:real):real;
var i:longint;
cos:real;
begin
test:=maxlongint;
for i:=1 to n do begin
cos:=dist(x[i],y[i],xx,yy);
if cos<test then test:=cos
end
end;
procedure init;
var i,j:longint;
x1,y1,x2,y2,y3,y4,mx,my,mm,cos:real;
begin
readln(maxx,maxy,n);
maxx:=maxx*10;maxy:=maxy*10;
for i:=1 to n do begin readln(x[i],y[i]);x[i]:=x[i]*10;y[i]:=y[i]*10 end;
p:=maxp;
ansx:=1;ansy:=1;ans:=0;
for i:=1 to p do begin xx[i]:=1+random(maxx);yy[i]:=1+random(maxy);f[i]:=test(xx[i],yy[i]) end;
t:=dist(maxx,maxy,0,0);
while t>maxt do begin
for i:=1 to p do begin
mx:=0;my:=0;mm:=0;
for j:=1 to maxl do begin
x1:=-10+random(21);y1:=10-sqr(x1);y2:=-y1;
x1:=x1*t;y1:=y1*t;y2:=y2*t;
x2:=x1+xx[i];y3:=y1+yy[i];y4:=y2+yy[i];
if (x2>=0)and(x2<=maxx) then begin
if (y3>=0)and(y3<=maxy) then begin
cos:=test(x2,y3);
if cos>mm then begin mm:=cos;mx:=x2;my:=y3 end
end;
if (y4>=0)and(y4<=maxy) then begin
cos:=test(x2,y4);
if cos>mm then begin mm:=cos;mx:=x2;my:=y4 end
end
end
end;
if mm>f[i] then begin f[i]:=mm;xx[i]:=mx;yy[i]:=my end;
if f[i]>ans then begin ans:=f[i];ansx:=xx[i];ansy:=yy[i] end;
end;
t:=t*0.8
end;
writeln('The safest point is (',ansx/10:0:1,', ',ansy/10:0:1,').')
end;
begin
randomize;
readln(i);
for i:=1 to i do init
end.