zoukankan      html  css  js  c++  java
  • 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));
        
    }
  • 相关阅读:
    pku 1061 青蛙的约会 扩展欧几里得
    莫比乌斯反演
    51Nod 1240 莫比乌斯函数
    51Nod 1284 2 3 5 7的倍数 容斥原理
    51Nod 1110 距离之和最小 V3 中位数 思维
    51Nod 1108 距离之和最小 V2 1096 距离之和最小 中位数性质
    HDU 2686 Matrix 多线程dp
    51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化
    HDU 1317XYZZY spfa+判断正环+链式前向星(感觉不对,但能A)
    设计模式(4)---单例模式
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11028815.html
Copyright © 2011-2022 走看看