zoukankan      html  css  js  c++  java
  • poj1328

    Radar Installation
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 73588   Accepted: 16470

    Description

    Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d. 

    We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates. 
     
    Figure A Sample Input of Radar Installations


    Input

    The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases. 

    The input is terminated by a line containing pair of zeros 

    Output

    For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

    Sample Input

    3 2
    1 2
    -3 1
    2 1
    
    1 2
    0 2
    
    0 0
    

    Sample Output

    Case 1: 2
    Case 2: 1
    

    Source

     
    中文版:见 codevs2625 雷达安装 传送门:http://codevs.cn/problem/2625/

    题解:

    刚开始不知道从哪分析,后经指点发现圆心位置是个突破口,首先得出每一个点所对应的圆心位置,注意若想覆盖最多,每一个圆都尽量做到使点刚好位于圆边界,比如我们左右两边各有一个水果,我们不确定能否拿得到两个,为了使得尽量拿到两个,我们会使左手刚好触碰到一个,伸右手去抓另一个,而不是直接以某一个为中心而忽略增大自身所能更加接近另一个的机会,于是问题就变成了求解圆心,按照圆心排序,不断更新雷达圆心,最终使数量最小。此外,注意代码注释部分。。。

    圆心竖轴为0,横轴坐标计算公式:

    r=x+sqrt(d*d-y*y)//圆心从左向右移动

    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define N 10100
    struct node{
        int x,y;double z;
    }land[N];
    inline bool cmp(const node &a,const node &b){
        return a.z<b.z;
    }
    int main(){
        int n,d,count,num=0;
        while(cin>>n>>d){
            if(!n&&!d) break;
            int flag=0;count=1;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&land[i].x,&land[i].y);
                land[i].z=(double)land[i].x+sqrt((double)(d*d-land[i].y*land[i].y));//圆心必须浮点数啊有木有
                if(abs(land[i].y)>d||d<=0) flag=1;//注意,当雷达无法笼罩时的情况输
            }
            if(flag){
                printf("Case %d: -1
    ",++num);continue;
            }
            sort(land+1,land+n+1,cmp); //对圆心位置从左到右进行排序  
            double x=land[1].z;
            for(int i=2;i<=n;i++){
                if((land[i].x-x)*(land[i].x-x)+land[i].y*land[i].y>d*d)
                    x=land[i].z,count++;  
            }
            printf("Case %d: %d
    ",++num,count);
        }
        return 0;
    }
  • 相关阅读:
    86. Partition List
    2. Add Two Numbers
    55. Jump Game
    70. Climbing Stairs
    53. Maximum Subarray
    64. Minimum Path Sum
    122. Best Time to Buy and Sell Stock II
    以场景为中心的产品设计方法
    那些产品经理犯过最大的错
    Axure教程:如何使用动态面板?动态面板功能详解
  • 原文地址:https://www.cnblogs.com/shenben/p/5646149.html
Copyright © 2011-2022 走看看