• P1158 导弹拦截


    P1158 导弹拦截

    题解

    这不是一道简单的贪心,他还要枚举

    我们首先要计算出导弹距离距离两个拦截系统分别的距离

    then,假设由一个拦截系统把它们全部拦截,然后逐一枚举导弹

    如果另一个拦截系统距离它更近我们显然是要更新的

     r1 表示拦截系统1的半径平方

     r2 表示拦截系统2的半径平方

    我们假设第一个拦截系统把它们全部拦截

    按照导弹与拦截系统1 的距离从小到大排序,然后从大到小枚举

    这样距离拦截系统1最远的导弹就被放在了最后面,但是不确定距离拦截系统2的距离

    (其实这样sort下来就相当于维护了一个前缀和,a[ i ].chang1表示拦截前 i 个导弹需要的最小 r1)

    那么 r1 一开始一定是等于 a[ n ].chang1

    从大到小枚举:

    假设现在有导弹 i ,它被拦截系统2拦截(前提是超出 r2 的拦截范围),那么前 i 个导弹一定都是被拦截系统2拦截(否则的话,根本就不会更新啊),那么剩下的导弹被拦截系统1 拦截,计算出此时的结果,与先前的结果比较,求解一个最小值

    最后还要比较一下更新 ans 和 r1 ,单个拦截更优还是两个一起拦截更优 

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<bits/stdc++.h>
    
    using namespace std;
    
    int x1,yi,x2,y2,x,y,n;
    int r1,r2,ans=1e9+6;
    
    struct node
    {
        int chang1,chang2;
    }a[100001];
    
    bool cmp(node x,node y)
    {
        return x.chang1 <y.chang1 ;
    }
    
    int main()
    {
        scanf("%d%d%d%d%d",&x1,&yi,&x2,&y2,&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            a[i].chang1 =(x-x1)*(x-x1)+(y-yi)*(y-yi);
            a[i].chang2 =(x-x2)*(x-x2)+(y-y2)*(y-y2);
        }
        
        sort(a+1,a+n+1,cmp);
        
        r1=a[n].chang1 ;
        
        for(int i=n-1;i>=1;i--)
        {
            if(r2<a[i+1].chang2 ) r2=a[i+1].chang2 ;
            ans=min(ans,a[i].chang1 +r2);
        }
        
        printf("%d",min(ans,r1));
        
    }
  • 相关阅读:
    ZOJ Problem Set–2417 Lowest Bit
    ZOJ Problem Set–1402 Magnificent Meatballs
    ZOJ Problem Set–1292 Integer Inquiry
    ZOJ Problem Set–1109 Language of FatMouse
    ZOJ Problem Set–1295 Reverse Text
    ZOJ Problem Set–1712 Skew Binary
    ZOJ Problem Set–1151 Word Reversal
    ZOJ Problem Set–1494 Climbing Worm
    ZOJ Problem Set–1251 Box of Bricks
    ZOJ Problem Set–1205 Martian Addition
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11028815.html
Copyright © 2020-2023  润新知