zoukankan      html  css  js  c++  java
  • BZOJ 2823: [AHOI2012]信号塔

    BZOJ 2823: [AHOI2012]信号塔

    标签(空格分隔): OI-BZOJ OI-最小圆覆盖


    Time Limit: 10 Sec
    Memory Limit: 128 MB


    Description

    在野外训练中,为了确保每位参加集训的成员安全,实时的掌握和收集周边环境和队员信息非常重要,集训队采用的方式是在训练所在地散布N个小型传感器来收集并传递信息,这些传感器只与设在集训地中的信号塔进行通信,信号塔接收信号的覆盖范围是圆形,可以接收到所有分布在该集训区域内所有N个小型传感器(包括在该圆形的边上)发出的信号。信号塔的功率与信号塔接收范围半径的大小成正比,因为是野外训练,只能使用事先储备好的蓄电设备,因此在可以收集所有传感器信息的基础上,还应使得信号塔的功率最小。小龙帮助教官确定了一种信号塔设置的方案,既可以收集到所有N个传感器的信号,又可以保证这个信号塔的功率是最小的。同学们,你们知道,这个信号塔的信号收集半径有多大,它应该设置在何处吗?
    Input

    共N+1行,第一行为正整数N(1≤N≤1000000),表示队员个数。接下来
    N行,每行两个实数用空格分开,分别是第i个队员的坐标X

    Output

    一行,共三个实数(中间用空格隔开),分别是信号塔的坐标,和信号塔 覆盖的半径。 (注:队员是否在边界上的判断应符合他到圆心的距离与信号塔接收半径之差的绝对值小于10^-6
    Sample Input

    5

    1.200 1.200

    2.400 2.400

    3.800 4.500

    2.500 3.100

    3.900 1.300

    Sample Output

    2.50 2.85 2.10

    HINT

    1≤N≤500000


    Solution####

    最小圆覆盖随机增量法


    Code####

    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    const double eps=1e-6;
    struct Point
    {
        double x,y;
    };
    double distan(Point p1,Point p2)
    {
    	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));  
    }
    int n;
    Point a[1000005],o;
    double r;
    void circum(Point p1,Point p2,Point p3)
    {
    	double a=2*(p2.x-p1.x),b=2*(p2.y-p1.y),c=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y,
    		   d=2*(p3.x-p1.x),e=2*(p3.y-p1.y),f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
    	o.x=(b*f-e*c)/(b*d-e*a);
    	o.y=(d*c-a*f)/(b*d-e*a);
    	r=distan(p1,o);
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        	scanf("%lf%lf",&a[i].x,&a[i].y);
        random_shuffle(&a[1],&a[n+1]);
        o=a[1],r=0;
        for(int i=2;i<=n;i++)  
     		if(distan(o,a[i])>r+eps)   
     		  {
        	   o=a[i];r=0;  
               for(int j=1;j<=i-1;j++) 
         		  if(distan(o,a[j])>r+eps)   
         			{
             		 o.x=(a[i].x+a[j].x)/2;  
             		 o.y=(a[i].y+a[j].y)/2;  
             		 r=distan(o,a[j]); 
             		 for(int k=1;k<=j-1;k++)
             			if(distan(o,a[k])>r+eps)
                		  circum(a[i],a[j],a[k]);
         			}  
     		  }
        printf("%.2lf %.2lf %.2lf
    ",o.x,o.y,r);
        return 0;
    }
    
  • 相关阅读:
    jdbc操作数据库并自动获取字段类型
    oracle sqlplus登陆命令
    2014木瓜移动校园招聘笔试题
    线段树总结
    JAVA的Split小技巧
    百度地图2.2框架黑屏和只有网格处理方法
    Zend Studio 实用快捷键大全
    Ext4中获取下拉框的值
    Java如何显示不同语言的时间?
    Java如何以不同国家的格式显示时间?
  • 原文地址:https://www.cnblogs.com/wuyuhan/p/5295502.html
Copyright © 2011-2022 走看看