poj1328

来源:互联网 发布:python cookie 登录 编辑:程序博客网 时间:2024/05/17 03:01

一道贪心也是醉了,刚开始没懂题意一直WA了好多次,后来查了下大神的博客,按照自己的思路又写了一遍,英语不好,就是这样,哎....

一道比较基础的贪心题

首先以小岛的坐标作圆与海岸线有交点,求出两交点的坐标,把他们当做线段[ai,bi];如果雷达放在这块区域,则小岛可以被覆盖
然后根据ai从小到大排序,这样就相当于求区间覆盖问题,需要注意的是这题的右端点是在变化的(即雷达所在位置为线段交集的最大值),
这样才能保证雷达能覆盖的区域最大,
当线段[ai,bi]左端的小值比雷达所在位置最大值还大时则需要再放置一个雷达,依次进行下去,知道所有的小岛被覆盖;
注意点:当覆盖范围比小岛纵坐标大时,怎么都不可能覆盖到小岛;

#include<iostream>#include<cmath>#include<algorithm>using namespace std;int case1=1;//记录case的大小int n;//小岛个数double r;//雷达覆盖半径struct data //以小岛为圆心雷达覆盖半径作圆,与海岸线的两个交点{    double left;    double right;}temp;bool comp(data a,data b){    return a.left<b.left;}int main(){      while(cin>>n>>r&&(n||r)){      data name[10002];//海岸线的交点数据      int num=1;   bool ceshi=false;//判断是否有小岛的纵坐标比雷达覆盖半径还远   for(int i=0;i<n;i++)   {       double x,y;        cin>>x>>y;       if(fabs(y)>r)//如果小岛纵坐标比雷达半径远       {        ceshi=true;       }       else{         name[i].left=x*1.0-sqrt((r*r-y*y));         name[i].right=x*1.0+sqrt((r*r-y*y));       }   }   if(ceshi)   {       cout<<"Case "<<case1<<": "<<"-1"<<endl;       case1++;   }    else   {     int num=1;    sort(name,name+n,comp);     temp=name[0];//雷达最远可以放置的地点   for(int i=1;i<n;i++)   {        if(temp.right<name[i].left)//如果雷达放置地点不能够达到第i个小岛覆盖的区域        {            temp=name[i];            num++;        }        else if(name[i].right<temp.right)//如果第i个小岛最大能放雷达的区域比现在放雷达的地点小        {            temp=name[i];//更改雷达最远可以放置的地点        }   }  cout<<"Case "<<case1<<": "<<num<<endl;  case1++;    }}return 0;}


0 0
原创粉丝点击