2017 Multi-University Training Contest - Team 9 HDU -6167:Missile Interception

本文探讨了一种导弹防御系统的问题,即如何确定最佳位置以确保能够拦截敌方发射的所有导弹。通过二分查找最长拦截时间和计算圆的交集来解决此问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

Missile Interception

 

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

 

 

Problem Description


A country's defense department has been informed there are n enemy's missile silos in an area. To avoid potential threat, DOD plans to build up a missile defense base to ensure any enemy's missiles can be shot down once they have been launched. Due to a tight budget, only one defense base can be built(which means all defense missiles can only be launched at one position). DOD knows the best strategy is to minimize the longest time required to intercept any enemy's missiles. The good news is that DOD has got a confidential document which reports each enemy's missiles' parameter, including their launching coordinate, direction and speed. DOD is free to launch its defense missile in any direction, but only AFTER enemy's missile has launched (or serious diplomatic crisis could occur). 
To simply the problem, we regard the area as a 2D plane. A missile can only fly alone a straight line with a fixed speed (its initial speed) and never comes down, until it successfully intercept or being intercepted by another missile. Now DOD wants to know with the best strategy described above, what's the longest time required to intercept any enemy's missile.
Note again, DOD doesn't need to intercept enemy's missiles as soon as they have been launched. The only requirement is not to launch the defense missile before enemy's missile.

Input

Multiple test cases (not exceed 5).
For each test case:
&#8226;  The first line contains two numbers n,V(2≤n,V <= 100), indicating the number of enemy's missiles and the speed of all defense missiles;
&#8226;  Then n lines follow. The ith line has 5 integers xi,yi,dxi,dyi,vi, which means a enemy's missile can be launched at coordinate (xi,yi) with direction vector (dxi,dyi), and its speed is vi.(0≤|xi|,|yi|,|dxi|,|dyi|≤100,1≤vi≤100)
It's guaranteed V>vmax.

Output

For each test case, output one line indicating the longest time mentioned above. Keep 4 decimal places.

 

Sample Input

2 2 2 0 3 0 1 0 0 3 1 1 2 2 0 0 0 1 1 0 2 0 -1 1

 

Sample Output

0.5081 0.3333

 

Source

2017 Multi-University Training Contest - Team 9

 

题解:考虑二分最长时间t,对于这个时间我们可以知道每颗导弹所能到达的最远位置。对于这些最远位置,我们可以以它们为圆心,作n个半径为t*V的圆,如果这n个圆有公共部分,则这个时间我们认为是可行的,否则不可行。那么这显然就是一个圆的面积交问题。
考虑这n个圆如果有公共面积,那么围城这个公共面积的边的定点一定是某(至少)两个圆所形成的交点。那么我们暴力枚举两个圆的交点,判断点到任意一个圆的圆心的距离是否会超过半径,如果都不超过,则一定存在公共面积。复杂度O(n^3)

 

 

#include<bits/stdc++.h>
using namespace std;
struct data
{
    double x,y;
    double vx,vy;
    double cos,sin;
    double v;
}p[200];
struct circle
{
    double x,y,r;
};
double dis(double x,double y,double x1,double y1){return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));}
int main()
{
    int n;double v;
    while(cin>>n>>v)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].vx,&p[i].vy,&p[i].v);
  //          p[i].cos=p[i].vx/sqrt(p[i].vx*p[i].vx+p[i].vy*p[i].vy);      开始的时候为了省事,先记录下来速度与x轴的cos值,结果因为精度问题WA了n次。。
  //          p[i].sin=p[i].vy/sqrt(p[i].vx*p[i].vx+p[i].vy*p[i].vy)       
        }
        double l=0,r=100000;
        double ans;
        while(r-l>1e-10)
        {
            double mid=(l+r)/2;
            int tag=0;
            vector<struct circle>q;
            for(int i=0;i<n;i++)
            {
                q.push_back((circle){p[i].x+mid*p[i].v*p[i].vx/sqrt(p[i].vx*p[i].vx+p[i].vy*p[i].vy),
				     p[i].y+mid*p[i].v*p[i].vy/sqrt(p[i].vx*p[i].vx+p[i].vy*p[i].vy),
				     mid*v});  //放入n个点构成的圆
            }
            for(int i=0;i<n;i++)
            {
                for(int j=i+1;j<n;j++)
                {
                    if(dis(q[i].x,q[i].y,q[j].x,q[j].y)-q[i].r-q[j].r>1e-10)continue;      //一开始用的是1e-7,然后WA了n次,改为1e-9又WA了n次。。。。
                    double x1=q[i].x , y1=q[i].y , r1=q[i].r;
                    double x2=q[j].x , y2=q[j].y , r2=q[j].r;
                    double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
                    double a=(r1*r1-r2*r2+d*d)/(2*d);
                    double h=sqrt(r1*r1-a*a);
                    double x=x1+(x2-x1)*a/d;
                    double y=y1+(y2-y1)*a/d;
                    double x3=x+h*(y2-y1)/d; double x4=x-h*(y2-y1)/d;
                    double y3=y-h*(x2-x1)/d; double y4=y+h*(x2-x1)/d;              //这一大段是求两圆相交的点
                    int flag=1;
                    for(int k=0;k<n;k++)
                    {
                        if(dis(q[k].x,q[k].y,x3,y3)-q[k].r>1e-10){flag=0;break;}        //1e-10

                    }
                    if(flag){tag=1;goto nex;}       //n个圆有公共点,退出循环
                    flag=1;
                    for(int k=0;k<n;k++)
                    {
                        if(dis(q[k].x,q[k].y,x3,y3)-q[k].r>1e-10){flag=0;break;}       //1e-10
                    }
                    if(flag){tag=1;goto nex;}       //n个圆有公共点,退出循环
                }
            }
            nex:if(tag)r=mid;
            else l=mid,ans=mid;
        }
        printf("%0.4lf\n",ans);
    }
    return 0;
}


 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值