题目描述
经过 $11$ 年的韬光养晦,某国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截。
当工作半径为 $0$ 时,则能够拦截与它位置恰好相同的导弹。
但该导弹拦截系统也存在这样的缺陷:每套系统每天只能设定一次工作半径。
而当天的使用代价,就是所有系统工作半径的平方和。
某天,雷达捕捉到敌国的导弹来袭。
由于该系统尚处于试验阶段,所以只有两套系统投入工作。
如果现在的要求是拦截所有的导弹,请计算这一天的最小使用代价。
输入格式
第一行包含 $4$ 个整数 $x_1、y_1、x_2、y_2$,每两个整数之间用一个空格隔开,表示这两套导弹拦截系统的坐标分别为 $(x_1,y_1)、(x_2,y_2)$。
第二行包含 $1$ 个整数 $N$,表示有 $N$ 颗导弹。
接下来 $N$ 行,每行两个整数 $x、y$,中间用一个空格隔开,表示一颗导弹的坐标 $(x,y)$,不同导弹的坐标可能相同。
输出格式
只有一行,包含一个整数,即当天的最小使用代价。
数据范围
$1 \\le N \\le 10^5$,所有坐标分量的绝对值都不超过 $1000$。
输入样例:
0 0 6 0
5
-4 -2
-2 3
4 0
6 -2
9 1
输出样例:
30
算法
(暴力枚举) $O(nlogn)$
直接暴力。
先用第一个雷达包围所有点,然后不断缩小第一个雷达的半径,每次圆边缘的点会从圈内出来,我们用第二个雷达去包含它 即可。
这样就可以枚举所有的情况。
C++ 代码
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;;
int n,a1,b1,a2,b2;
struct PP{
int x,y,d;
bool operator<(const PP &W)const{
return d<W.d;
}
}pp[N];
int f(int x1,int y1,int x2,int y2)
{
int dx=x1-x2,dy=y1-y2;
return dx*dx+dy*dy;
}
int main()
{
int i,x,y,ans,r=0;
scanf("%d%d%d%d%d",&a1,&b1,&a2,&b2,&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
pp[i]={x,y,f(x,y,a1,b1)};
}
sort(pp,pp+n);
reverse(pp,pp+n);
ans=pp[0].d;
for(i=1;i<=n;i++) r=max(r,f(pp[i-1].x,pp[i-1].y,a2,b2)),ans=min(ans,pp[i].d+r);
printf("%d\n",ans);
return 0;
}
这个
sort
的时间复杂度是$O(nlogn)$吧已修改!
可以用upper_bound或者lower_bound啊
大哥,我喜欢直接枚举啊
服了