poj.1328贪心

本题的题意为:在x轴上有地雷,有一个半径为d的范围,现在岛位于x轴上或上方,(注意可能在x轴上),现要求求出能将所有岛包含的地雷的最小个数。

那么这题,我们可以模拟成这样的问题:有一系列的点,要你画圆,将所有这些点包含,最少的园的个数。通常我们会从左到右的画圆,每个园包含数量最多的点,直到不行为止,这时画另一个园,一直这样下去,就可以求出最小的数量了。那么这就是符合贪心的条件了:局部最优解,具体到本题就对应于一个园所能包含的最大的点数。理解了这点就不难解决这题了。

下面是代码:

//#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
//using namespace std;
#define Max 1000
#define maxn(a,b) (a)>(b)?(a):(b)
#define minn(a,b) (a)<(b)?(a):(b)
struct Por
{
	int x;
	int y;
}node[Max];
int n,d,ans;
inline double L_limit(int ,int );
inline double R_limit(int ,int );
int cmp(const void*,const void*);
int main()
{
	int time=1;
	while(scanf("%d%d",&n,&d),n)
	{
		int i;
		bool trag=true;
		for(i=0;i<n;i++){
		scanf("%d%d",&node[i].x,&node[i].y);
		if(node[i].y<0 || node[i].y>d)
			trag=false;
		}
		if(!trag || d<=0)
			printf("Case %d: -1\n",time++);
		else
		{
		qsort(node,n,sizeof(Por),cmp);
		double left=L_limit(node[0].x,node[0].y);
		double right=R_limit(node[0].x,node[0].y);
		ans=1;
		for(i=1;i<n;i++){
			double xL=L_limit(node[i].x,node[i].y);
			double xR=R_limit(node[i].x,node[i].y);
			if(xL<=right){
				left=maxn(xL,left);
				right=minn(xR,right);
			}
			else{
				ans++;
				left=xL;
				right=xR;
			}
		}
		printf("Case %d: %d\n",time++,ans);
		}
	}
	return 0;
}
inline double L_limit(int x,int y){
	return x-sqrt(double(d*d-y*y));
}
inline double R_limit(int x,int y){
	return x+sqrt(double(d*d-y*y));
}
int cmp(const void*p,const void*q){
	if(((Por *)p)->x!=((Por *)q)->x)
		return ((Por *)p)->x-((Por *)q)->x;
	else
		return ((Por *)p)->y-((Por *)q)->y;

其实这题是模拟与贪心的结合,另外注意d<=0时的情况,还有点在坐标上的情况。
下面是测试数据:
2 5
-3 4
-6 3


4 5
-5 3
-3 5
2 3
3 3

20 8
-20 7
-18 6
-5 8
-21 8
-15 7
-17 5
-1 5
-2 3
-9 6
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 7
9 6
10 5
0 0

2 3
0 2
2 3

2 3
0 2
1 3

3 3
1 2
-3 2
2 4

8 5
2 4
-4 4
-3 3
-3 1
-3 0
-1 0
0 5
6 0

3 0
1 2
-3 1
2 1

3 2
1 2
-3 1
2 1

1 2
0 2


2 3
0 2
2 3

4 -5
4 3
4 3
2 3
6 -9



3 -3
1 2
-3 2
2 1

6 2
1 2
1 2
1 2
-3 1
2 1
0 0

1 2
0 2

2 3
0 2
1 3

3 10
1 10
2 3
4 5

3 5
1 10
2 3
4 5

4 7
1 10
2 3
4 5
0 0

3 9
1 10
2 3
4 5
0 0

================结果
Case 1: 1
Case 2: 2
Case 3: 4
Case 4: 1
Case 5: 1
Case 6: -1
Case 7: 3
Case 8: -1
Case 9: 2
Case 10: 1
Case 11: 1
Case 12: -1
Case 13: -1
Case 14: 2
Case 15: 1
Case 16: 1
Case 17: 1
Case 18: -1
Case 19: -1
Case 20: -1
希望对大家有用。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值