poj 1328 Radar Installation (貪心)

Radar Installation
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 51376   Accepted: 11526

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

該題題意是爲了求出能夠覆蓋所有島嶼的最小雷達數目,而由題目我們可以求出每個島嶼雷達能覆蓋的區間,該區間在島嶼橫座標兩邊對稱的長度[x-sqrt(r*r-y*y),x+sqrt(r*r-y*y)];然後我們對島嶼按左區間從小到大排序,說到這裏,我們腦海中就浮現出來了貪心的經典活動安排問題,把這些區間看成一個活動的【開始時間--結束時間】,要求我們儘可能地選擇一個方案最多的活動,前提是活動要兼容,即時間不衝突,而所求的最多方案是就是我們要求的最小雷達數目;例如這組數據;
3 2
0 0
1 2
4 0
我們用一個結構體 數組len【i】.right,len【i】.left分別記錄當前的區間端點,然後將第一個島嶼的
len【i】.rigth與其後面的島嶼的雷達放置區間左端點一個的去對比(如果遇到有一個島嶼k的雷達放置區的右端點比其還小就要將right的
值更新到len【k】.right)直到遇到一個島嶼的雷達放置區的左端點不在其範圍內就將數據更新到這個島嶼的雷達區間範圍此時ans要+1;


PS:題目中數據有出現r<=0,直接輸出Case #: -1即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<stdlib.h>
using namespace std;
struct Class{
    double x;
    double y;
}zb[1005];

struct Std{
    double s;
    double e;
}len[1005];
double r;
int ans,n;
bool cmp(Class a,Class b)
{
    return a.x<b.x;
}

void worklen()//將每個島嶼各自對應的能夠放雷達的區域計算出來
{
    for(int i=0;i<n;i++)
    {
        /*cout<<len[i].s<<" "<<len[i].e<<endl;*/
        len[i].s=zb[i].x-sqrt(r*r-(zb[i].y*zb[i].y));
        len[i].e=zb[i].x+sqrt(r*r-(zb[i].y*zb[i].y));

    }
}
void work()
{
    int j;
    int l=0;

          for(j=1;j<n;j++)
             {
                 if(len[j].e<len[l].e)
                 {
                     l=j;//當有第j個島嶼雷達的放置區比l個島嶼的小時 注意要把最小的作爲比較標準
                 }
                 else if(len[l].e<len[j].s)
                     {
                        ans++;
                        l=j;
                     }

             }

        return ;
}

int main()
{
    int i,flag,t=1;
    while(cin>>n>>r,n||r)
    {

        flag=0;
        ans=1;
        for(i=0;i<n;i++)
          cin>>zb[i].x>>zb[i].y;

            for(i=0;i<n;i++)
                if(fabs(zb[i].y)>r)
                   {
                       flag=1;
                   }
        if(flag)
            {
                cout<<"Case "<<t<<": "<<"-1"<<endl;
                t++;
            }
        else
        {
            sort(zb,zb+n,cmp);
            /*for(i=0;i<n;i++)
                cout<<zb[i].x<<" "<<zb[i].y<<endl;*/
            worklen();
            work();
            cout<<"Case "<<t<<": "<<ans<<endl;
            t++;

        }

    }

    return 0;
}




發佈了107 篇原創文章 · 獲贊 4 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章