POJ 1328 Radar Installation

地址:http://poj.org/problem?id=1328

题意:在一个笛卡尔坐标系中有一些点(岛屿且其y坐标都大于零),在x轴上确定安装雷达的点,这些点的覆盖范围是给定半径的圆,至少要安装多少雷达可以覆盖所有岛屿,若无解则输出-1.

思路:从每一个岛屿入手,以岛屿为圆心雷达覆盖半径为半径画圆,与x轴交一个区间,显然这个区间内任意一点安设雷达都可以覆盖这个岛屿,那么问题便转化成了这些区间之间的关系。

解法:

1.先将各点以x坐标递增排序,算出各区间左右值left[i],right[i].

2.先将雷达temp安装在right[i]上,若left[i+1]<temp<right[i+1],显然可以覆盖下一个岛屿。若left[i+1]>temp显然需要增设雷达,雷达计数+1,temp右移至right[i+1]。还有一种情况,即right[i+1]<temp,这是由于y值不同可能存在的,但显然left[i]<left[i+1],此时需要将temp左移至right[i+1]。遍历所有区间可得结果。


#include<iostream>
#include<cmath>
using namespace std;

#define N 1005

int main()
{
    int n,i,j,count,t;
    t=1;
    int flag;
    double x[N],y[N];
    double left[N],right[N];
    double r,tx,ty,temp;
    while(cin>>n>>r&&n&&r)
    {
       count=1;
       flag=0;
       for(i=0;i<n;i++)
       {
         cin>>x[i]>>y[i];
         if(y[i]>r) flag=1;
       }
       if(flag)
       {
         cout<<"Case "<<t<<": -1"<<endl; 
         t++; 
         continue;       
       }
       for(i=0;i<n-1;i++)
          for(j=0;j<n-i-1;j++)
          {
             if(x[j]>x[j+1])
             {
                tx=x[j];
                ty=y[j];
                x[j]=x[j+1];
                y[j]=y[j+1];
                x[j+1]=tx;
                y[j+1]=ty;          
             }            
          }           
       for(i=0;i<n;i++)
       {
         left[i]=x[i]-sqrt(r*r-y[i]*y[i]);
         right[i]=x[i]+sqrt(r*r-y[i]*y[i]);
       } 
       temp=right[0];     
       for(i=1;i<n;i++)
       {
         if(temp<left[i])
         {
           temp=right[i];
           count++;      
         }
         else
         {
             if(temp>right[i])
             temp=right[i]; 
         }             
       }
       cout<<"Case "<<t<<": "<<count<<endl; 
       t++;                         
    }
    return 0;
}


你可能感兴趣的:(poj,poj,poj,贪心)