《算法竞赛进阶指南》0x07贪心 POJ1328
作者:互联网
题目链接:http://poj.org/problem?id=1328
给出平面上N个点,要求在横轴上放置最少的点来覆盖N个点,其中每个点的覆盖半径都是R,可以将问题转化成用点覆盖线段的问题,计算N个点中每个点的可被管辖区间,
转化成求每个线段中至少有一个点的最少的点数。贪心思想。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define maxn 100010 const double eps=1e-6; struct node{ int x,y; double l,r;//l,r为能够管辖这个点的区间 bool operator < (const node& a)const { return l<a.l;//按照左端点进行升序排序 } }a[maxn]; int n,d; int main (){ int kase=0; while(cin>>n>>d){ if(n==0 && d==0)break; for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y); bool flag=true; for(int i=1;i<=n;i++){ if(a[i].y>d){ flag=false; break; } double k=sqrt((double)d*d-(double)a[i].y*a[i].y); a[i].l=a[i].x-k,a[i].r=a[i].x+k; } if(!flag){ cout<<"Case "<<++kase<<": "<<-1<<endl; continue; } sort(a+1,a+n+1); int ans=0; double pos=-1e10; for(int i=1;i<=n;i++){ if(pos+eps<a[i].l){//浮点数无法严格比较 ans++;//重新开一个段 pos=a[i].r; }else{ pos=min(pos,a[i].r);//在满足第i个区间的情况下,使点尽量靠后,之前能覆盖的点不受影响 } } printf("Case %d: %d\n",++kase,ans); } }
标签:POJ1328,const,进阶,int,double,0x07,flag,include,id 来源: https://www.cnblogs.com/randy-lo/p/13139363.html