Description
给出两个圆心的坐标(x1,y1)和(x2,y2)以及n个点的坐标,两个圆的半径分别为r1和r2,要求这n个点必须在这两个圆所覆盖的区域内,问r1*r1+r2*r2的最小值是多少
Input
第一行五个整数n,x1,y1,x2,y2分别表示点数和两个圆心的坐标,之后n行每行两个整数x,y表示该点坐标(1<=n<=2000,-10^7<=x1,y1,x2,y2,x,y<=10^7)
Output
输出r1*r1+r2*r2的最小值
Sample Input
2 -1 0 5 3
0 2
5 2
Sample Output
6
Solution
简单题,先求出每个点到(x1,y1)的距离dis[i],排个序之后枚举i,使得前i个点在圆1的区域内,后n-i个点在圆2的区域内,求出后n-i个点到(x2,y2)距离的最大值max,更新ans=min(ans,dis[i]+max)即可
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x7f7f7f7f7f7f7f
#define maxn 2222
typedef long long ll;
struct node
{
ll x,y;
ll dis;
}f1,f2,f[maxn];
int n;
ll ans;
ll get_dis(node a,node b)
{
return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}
int cmp(node a,node b)
{
return a.dis<b.dis;
}
int main()
{
while(~scanf("%d%I64d%I64d%I64d%I64d",&n,&f1.x,&f1.y,&f2.x,&f2.y))
{
ans=INF;
f[0].dis=0;
for(int i=1;i<=n;i++)
{
scanf("%I64d%I64d",&f[i].x,&f[i].y);
f[i].dis=get_dis(f1,f[i]);
}
sort(f+1,f+n+1,cmp);
for(int i=0;i<=n;i++)
{
ll temp=0;
for(int j=i+1;j<=n;j++)
temp=max(temp,get_dis(f2,f[j]));
ans=min(ans,temp+f[i].dis);
}
printf("%I64d\n",ans);
}
return 0;
}