[SGU]110. Dungeon

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值