登 录
//贪心,注意贪心的方式,一开始我用从左往右对每一个点所对应的最右圆心坐标,接着逐步右移判断,看了POJ上的大牛讨论,知道这个算法是错误的,于是进行了改正 //正确的贪心算法应当是求出每个点它所满足的圆心范围,接着将问题转化为多区间选点问题。 //即在N个闭区间上取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个) #include<iostream> #include<cmath> using namespace std; struct coordinate//坐标结构体(x,y) { int x,y; }p[1001]; struct interval//区间结构体[a,b] { double a; double b; }b[1001]; int cmp_interval(const void *a,const void *b) { interval *A = (interval*) a; interval *B = (interval*) b; return (*A).b > (*B).b ? 1: -1; }//qsort的比较函数 double search(coordinate a,int d) { double x; x = sqrt((double)(d*d - a.y*a.y)) + a.x; return x; }//找出所给坐标对应的圆心允许范围 int main() { int n,d,c = 0,r;//r = number of radar,c = case bool impossible; while(cin >> n >> d) { if(n == 0)break; ++c; impossible = 0; r = 1; for(int i = 0;i < n;++i) { cin >> p[i].x >> p[i].y; if(abs(p[i].y) > d) impossible = 1; b[i].a = 2*p[i].x - search(p[i],d); b[i].b = search(p[i],d); } qsort(b,n,sizeof(b[0]),cmp_interval);//将区间按右边界从小到大排序 if(impossible) cout <<"Case "<< c <<": " << -1 <<endl; else { int temp = 0; //贪心过程,策略是对包含区间取最右端的点,若左边界大于之前区间的右边界,则点数必须增加才能满足条件 for(int i = 0;i < n;++i) { if(b[i].a > b[temp].b) { ++r; temp = i; } } cout <<"Case "<< c <<": " << r << endl; } } return 0; }
抱歉!评论已关闭.