Analysis
一道计算几何题,反正是NOIP肯定不会考的东西……一直跪在精度上,最后到网上看了看别人的代码,参考了一下还是A了。思路倒是很清晰,只需要把三维空间里的直线用向量一类的东西表示出来,然后应用立体几何平面化的思想把反射的公式推一下就可以了……
Accepted Code
const
zero=1e-8;
var
b:array[1..50,1..4]of longint;
m,st,en,v,w,p,q,tmp:array[1..3]of extended;
minl,l,d:extended;
i,j,k,n,min,last:longint;
function distance(xx,yy,zz,r:longint):extended;
var
b,c,delta,fd,dis:extended;
i:longint;
begin
fd:=sqrt(sqr(en[1])+sqr(en[2])+sqr(en[3]));
b:=-2*(en[1]*(xx-st[1])+en[2]*(yy-st[2])+en[3]*(zz-st[3]))/fd;
c:=sqr(xx-st[1])+sqr(yy-st[2])+sqr(zz-st[3])-sqr(r);
delta:=sqr(b)-4*c;
if delta<-zero then
begin
distance:=20000000;
exit;
end;
dis:=(-b-sqrt(delta))/2;
if dis<-zero then
begin
distance:=20000000;
exit;
end;
fd:=dis/fd;
for i:=1 to 3 do
q[i]:=st[i]+fd*en[i];
tmp[1]:=q[1]-xx;
tmp[2]:=q[2]-yy;
tmp[3]:=q[3]-zz;
fd:=-2*(en[1]*tmp[1]+en[2]*tmp[2]+en[3]*tmp[3])/(sqr(tmp[1])+sqr(tmp[2])+sqr(tmp[3]));
for i:=1 to 3 do
w[i]:=fd*tmp[i]+en[i];
distance:=dis;
end;
begin
readln(n);
for i:=1 to n do
readln(b[i,1],b[i,2],b[i,3],b[i,4]);
readln(st[1],st[2],st[3],en[1],en[2],en[3]);
for i:=1 to 3 do
en[i]:=en[i]-st[i];
last:=0;
for j:=1 to 11 do
begin
minl:=10000000;
min:=0;
for i:=1 to n do
begin
if i=last then
continue;
l:=distance(b[i,1],b[i,2],b[i,3],b[i,4]);
if l<minl then
begin
p:=q;
v:=w;
minl:=l;
min:=i;
end;
end;
if min=0 then
begin
writeln;
halt;
end;
if j=11 then
begin
writeln(' etc.');
halt;
end;
if j=1 then
write(min)
else
write(' ',min);
st:=p;
en:=v;
last:=min;
end;
end.