POJ 1328(排序+贪心)

题目链接: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;
}



你可能感兴趣的:(POJ 1328(排序+贪心))