zoukankan      html  css  js  c++  java
  • noip2010 导弹拦截&&vijos1810

    描述

    经过11 年的韬光养晦,某国研发出了一种新的导弹拦截系统,凡是与它的距离不超过其工作半径的导弹都能够被它成功拦截。当工作半径为0 时,则能够拦截与它位置恰好相同的导弹。但该导弹拦截系统也存在这样的缺陷:每套系统每天只能设定一次工作半径。而当天的使用代价,就是所有系统工作半径的平方和。 某天,雷达捕捉到敌国的导弹来袭。由于该系统尚处于试验阶段,所以只有两套系统投入工作。如果现在的要求是拦截所有的导弹,请计算这一天的最小使用代价。

    格式

    输入格式

    第一行包含4 个整数x1、y1、x2、y2,每两个整数之间用一个空格隔开,表示这两套导弹拦截系统的坐标分别为(x1, y1)、(x2, y2)。

    第二行包含1 个整数N(1 ≤ N ≤ 100000)。表示有N 颗导弹。
    接下来N 行,每行两个整数x、y,中间用一个空格隔开,表示一颗导弹的坐标(x, y)。不同导弹的坐标可能相同。
    所有坐标分量的绝对值都不超过1000。

    输出格式

    只有一行,包含一个整数,即当天的最小使用代价。

    样例1

    样例输入1

    0 0 10 0 
    2 
    -3 3  
    10 0 
    
    

    样例输出1

    18
    
    

    样例2

    样例输入2

    0 0 6 0 
    5  
    -4 -2 
    -2 3    
    4 0 
    6 -2 
    9 1
    
    

    样例输出2

    30
    
    

    限制

    每个测试点1s。

    提示

    两个点(x1, y1)、(x2, y2)之间距离的平方是(x1− x2)2+(y1−y2)2。

    两套系统工作半径r1、r2 的平方和,是指r1、r2 分别取平方后再求和,即r12 +r22 。
    样例1说明:
    样例1 中要拦截所有导弹,在满足最小使用代价的前提下,两套系统工作半径的平方分 别为18 和0。
    样例2说明:
    样例中的导弹拦截系统和导弹所在的位置如下图所示。要拦截所有导弹,在满足最小使用代价的前提下,两套系统工作半径的平方分别为20 和10。
    img

    来源

    NOIP2010普及组


    这种最终答案受两个因素影响的题目

    想到枚举(二分)一个因素,然后再暴力求另一个因素

    即枚举一个系统的半径(注意到坐标绝对值范围不超过1000)

    我刚开始想到了这个方法

    但我想的是每一次枚举后都扫描一遍

    这样的复杂度是会爆的

    看了题解之后才发现枚举一个因素的时候

    因为是连续枚举嘛

    所以另一个因素的变化也是连续的(即随着一个系统的半径的增大,它能覆盖到的点就会增加,而需要另一个系统覆盖的点就减少这几个)

    因此想到要把点按离这个系统中心的距离排序

    发现如果是递增的话

    另一个系统取最大值不能O(1)处理

    所以想到要递减

    这样另一个系统的最大值就好办了

    傻了傻了

    吸取经验(总是傻在这种地方)

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    struct node
    {
    	int dis1,dis2;
    }e[100005];
    bool cmp(node a,node b)
    {
    	return a.dis1<b.dis1;
    }
    int main()
    {
    	int x1,y1,x2,y2;int min=2*1e9;
    	scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
    	int n,p,q;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d %d",&p,&q);
    		e[i].dis1=(p-x1)*(p-x1)+(q-y1)*(q-y1);
    		e[i].dis2=(p-x2)*(p-x2)+(q-y2)*(q-y2);
    	}
    	std::sort(e+1,e+1+n,cmp);
    	int max=0;
    	for(int i=n;i>=1;i--)
    	{
    		max=max>e[i+1].dis2?max:e[i+1].dis2;
    		min=min<max+e[i].dis1?min:max+e[i].dis1;
    	}
    	printf("%d
    ",min);
    	return 0;
    }


  • 相关阅读:
    linux 静态库和动态库(共享库)的制作与使用(注意覆盖问题)转
    手机号码格式正则表达式
    项目去除TFS关联、迁移重部署
    Excel中VLOOKUP函数的用法和注意点
    自定义打赏插件
    分享一个无需注册,无次数限制的Smile聊天机器人接口
    TCP/IP
    Java字典树
    平衡二叉树结构 AVL
    二叉搜索树(二叉排序树)BST
  • 原文地址:https://www.cnblogs.com/Brian551/p/7353008.html
Copyright © 2011-2022 走看看