洛谷P1158导弹拦截

来源:互联网 发布:gsm网络的sim卡是什么 编辑:程序博客网 时间:2024/05/22 05:29

这道题是贪心,对于每一个每个点到A和B的距离都是确定的,所以我们可以只考虑一个A所要去覆盖的点,A不能覆盖到的点显然就要让B来覆盖,设rai,rbi为第i个点分别到A和B的距离。在对rai进行排序之后,可以得到一个ra1<=ra2<=ra3<=ra4...<=rai<=...ran的序列,可以证明当i<j的时候取j显然会包括i,然后我们就可以求解了。同时还有一点就是循环从后往前搜是更优的,因为rbi是无序的,从后往前更新一下B的最大半径省去了从前往后搜的很多细节问题。

#include <cstdio>#include <cstdlib>#include <ctype.h>#include <algorithm>#define ll long long#define max(a,b) a>b?a:b#define min(a,b) a<b?a:btemplate<typename T>inline T read(){    T f=0,x=1;    char c=getchar();    while(!isdigit(c)){if(c=='-')x=-1;c=getchar();}    while(isdigit(c))f=f*10+c-'0',c=getchar();    return f*x;}const int maxn=100005;int Ax,Ay,Bx,By;int n,x,y;struct Node{    int A,B;    bool operator <(const Node &b)const{        return A<b.A;    }}P[maxn];int dist(int A,int B,int C,int D){    return (A-C)*(A-C)+(B-D)*(B-D);}int main(){    Ax=read<int>();    Ay=read<int>();    Bx=read<int>();    By=read<int>();    n=read<int>();    for(int i=1;i<=n;i++){        x=read<int>();        y=read<int>();        P[i].A=dist(Ax,Ay,x,y);        P[i].B=dist(Bx,By,x,y);    }    std::sort(P+1,P+1+n);    int ans=1<<30,r2=0;     for(int i=n;i>=1;i--){        r2=max(r2,P[i+1].B);        ans=min(ans,r2+P[i].A);    }    printf("%d\n",ans);     return 0;}
原创粉丝点击