矩阵中找一点使该点到各已知陷阱中最近的最远。
如果是神牛,自然可以用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.