wikioi1128 导弹拦截(理解思路)

来源:互联网 发布:windows改变图标 编辑:程序博客网 时间:2024/04/30 01:55

设一个结构体存:编号n、距离x。

称两个拦截仪器分别为A和B。

读入时分别算出到A、B的距离的平方。(因为答案是平方和,且开方不开方大小关系不会变,所以不必开方,还便于后续处理)

分别存到a[i(1~n)].x,b[i].x中。

此外将a[0]和b[0]设为A、B半径为0时的状态。

按距离x大到小快排A(包括a[0],因此a[0]一定被排到最后一位a[n])

ma、mb分别存各状态时的A、B代价(答案ans=ma+mb)

初始设i=0,即A处理全部,B全不处理,此时初值ans=a[0].x+0;

写一个while循环(i<=n),

每次B处理此时距离A最远的点,即mb=b[a[i].n].x(通过结构体的编号检索)。

然后再做while循环(i<=n&&b[a[i].n].x<=mb),满足时i++,每次i至少加1。

此时ma=a[i].x,即B不能处理的点中A的最大距离。

每次ans=ans与ma+mb中的最小值。


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct aaaa{int l,hao;};
aaaa a[100001];
int b[100001],n;
bool cmp(aaaa a1,aaaa a2){
return a1.l>a2.l;
}
int main()
{
    int x1,y1,x2,y2;
    cin>>x1>>y1>>x2>>y2;
    cin>>n;
    for(int i=1;i<=n;i++){
        int x,y;
        cin>>x>>y;
        a[i].hao=i;
        a[i].l=(x1-x)*(x1-x)+(y1-y)*(y1-y);
        b[i]=(x2-x)*(x2-x)+(y2-y)*(y2-y);
    }
    sort(a+1,a+1+n,cmp);
    int mins=a[1].l,k=1;
    while(k<=n){
            int mb=b[a[k].hao];
        while(k<=n&&b[a[k].hao]<=mb){
            k++;
        }
        int ma;
        if(k>n)ma=0;
        else ma=a[k].l;
        mins=min(mins,ma+mb);
    }
    cout<<mins;
    return 0;
}

0 0