您的位置:首页 > 大数据 > 人工智能

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

2017-08-23 11:42 393 查看


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:

•  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;

•  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

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐