CodeForces 617 C. Watering Flowers(水~)

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

你可能感兴趣的:(CodeForces 617 C. Watering Flowers(水~))