题目链接:http://poj.org/problem?id=1328
题意:给出一个笛卡尔坐标系,在y轴上半轴给出多个点,以x轴上的点为圆心画圆,要求能覆盖y轴上所有的点,至少需要多少个圆?如果不存在,则输出-1;
思路:
首先说一下错误思路:将所有点从左向右排序,然后优先考虑左边的点,画圆覆盖该点,然后尽量将圆心右移,这是一个错误的做法,可以参考以下数据:
2 3
0 2
1 3
然后说一下正确的思路:将所有的点从左向右排序,以每个点圆心画圆,找出与x轴相交的区间,即该点所在圆的圆心所在区间,然后将从n个区间内找出最少不相交区间的个数。
最后,再说一下,y<0不知道有没有这样的数据,没判断也过了,但是d<0需要判断。
具体代码实现如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn=1010; int T,n,d; struct node{ double sx; double ex; }q[maxn]; bool cmp(node a,node b){ return a.sx<b.sx; } int main(){ #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif int cas=1; while(~scanf("%d%d",&n,&d)){ if(!n&&!d) break; int x,y; bool flag=false; for(int i=0;i<n;i++){ scanf("%d%d",&x,&y); if(y>d||flag==true){ flag=true; continue; } double tmp=sqrt((double)(d*d-y*y)); q[i].sx=(double)(x-tmp); q[i].ex=(double)(x+tmp); } if(flag==true||d<0){ printf("Case %d: %d\n",cas++,-1); continue; } sort(q,q+n,cmp); int ans=1; double axis=q[0].ex; for(int i=1;i<n;i++){ if(q[i].sx>axis){ ans++; axis=q[i].ex; } else if(q[i].ex<axis){ axis=q[i].ex; } } printf("Case %d: %d\n",cas++,ans); } return 0; }