URAL 1600 Airport

题意: 有n个飞机,都有自己的初始位置和行驶方向,问第一次距离小于d的时间,和这两架飞机。

思路:三分+二分

枚举任意两个飞机,在0-INF三分找最近的时间tmp,在0-tmp找距离为d的时间。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <string>
#define LL long long
#define DB double

using namespace std;
const DB INF = 1e200;
const DB EPS = 1e-5;
struct cpoint3{
    DB x,y,z;
    void get(){scanf("%lf%lf%lf",&x,&y,&z);}
    cpoint3(){}
    cpoint3(DB a,DB b,DB c){x=a,y=b,z=c;}
};
struct cvector3{
    DB x,y,z;
    cvector3(){}
    cvector3(DB a,DB b,DB c){x=a,y=b,z=c;}
    void get(){scanf("%lf%lf%lf",&x,&y,&z);}
};
cvector3 operator*(DB a,cvector3 b)
{
    return cvector3(a*b.x,a*b.y,a*b.z);
}
cpoint3 operator+(cpoint3 a,cvector3 b)
{
    return cpoint3(a.x+b.x,a.y+b.y,a.z+b.z);
}
int n;
const int N = 509;
cpoint3 re[N];
cvector3 rat[N];
DB d;
DB dist(cpoint3 a,cpoint3 b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
cpoint3 a1,a2;
cvector3 v1,v2;
DB three(DB l,DB r)
{
    DB mid,mmid;
    while(r-l>EPS)
    {
        mid = (l+r)/2;
        mmid = (mid+r)/2;
        DB d1 = dist(a1+mid*v1,a2+mid*v2);
        DB d2 = dist(a1+mmid*v1,a2+mmid*v2);
        if(d1<d2)
            r = mmid;
        else
            l = mid;
    }
    return l;
}
DB two(DB l,DB r)
{
    DB mid;
    while(r-l>EPS)
    {
        mid = (l+r)/2;
        DB d1 = dist(a1+mid*v1,a2+mid*v2)-d;
        if(d1<0)
            r = mid;
        else
            l = mid;
    }
    //cout<<l<<endl;
    //cout<<dist(a1+l*v1,a2+l*v2)<<"- "<<d+EPS<<endl;
    if(l<=EPS||dist(a1+l*v1,a2+l*v2)>d*(1+EPS)) return -1;
    return l;
}
DB solve(int a,int b)
{
    a1=re[a],a2=re[b];
    v1=rat[a],v2=rat[b];
    DB tmp = three(-1,1e8);
    //cout<<tmp<<endl;
    return two(-1,tmp+EPS);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    scanf("%d%lf",&n,&d);
    int a,b;DB t=INF;
    for(int i=0;i<n;i++)
    {
        re[i].get();rat[i].get();
    }
    for(int i=0;i<n;i++)
    {
        for(int j=i+1;j<n;j++)
        {
            DB tmp = solve(i,j);
           // cout<<i+1<<" "<<j+1<<" "<<tmp<<endl;
            if(tmp>-EPS)
            {
                if(t>tmp)
                {
                    t = tmp;
                    a = i+1,b=j+1;
                }
            }
        }
    }
    if(t+EPS>=INF)
    {
        printf("OK\n");
    }else
    {
        printf("ALARM!\n%.9lf %d %d\n",t,a,b);
    }
    return 0;
}


你可能感兴趣的:(二分,计算几何,三分)