zoj1360贪心

//题意理解:以x轴为海岸线,x轴以上为海域,以下为大陆,海上有若干岛屿
//在海岸线上放置雷达,雷达的覆盖半径为d,求覆盖所有岛屿所需雷达的最小数量
//  以每一个岛屿为圆心,d为半径画圆交x轴与两点x1,x2。得到区间【x1,x2】
//将区间以左端值大小从小到大排序,从左到右扫描
//如果多个区间有公共区,则雷达放在公共区,便能覆盖产生这些区间的岛屿
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
#define max 1002
typedef struct A
{
	int x,y;
}node;//岛屿坐标数据结构
typedef struct B
{
	double l,r;
}interval;//区间数据结构
int n,d;
node nodes[1002];
interval intervals[1002];
int getinterval(int a,int b,int j);//以岛屿坐标为圆心,d为半径的圆与横轴的交点作为区间的左右端点
int doit();//贪心求解,
int cmp(const void *a,const void *b);
int main()
{
	FILE*fp=fopen("D:input1.txt","r");
	int i,kegao,ct=0;
	fscanf(fp,"%d%d",&n,&d);
	while(d&&n)
	{
			kegao=1;
			for(i=0;i<n;i++)
			{
				fscanf(fp,"%d%d",&nodes[i].x,&nodes[i].y);
				if(nodes[i].y>d)//不能覆盖的情况
				{
					kegao=0;
					break;
				}
			}
			if(kegao)
			{
				for(i=0;i<n;i++)
					getinterval(nodes[i].x,nodes[i].y,i);
				qsort(intervals,n,sizeof(interval),cmp);//将区间以左端值大小从小到大排序
				printf("Case %d: %d\n",++ct,doit());
			}
			else
				printf("Case %d: -1\n",++ct);
		fscanf(fp,"%d%d",&n,&d);
	}
	return 0;
}
int getinterval(int a,int b,int j)
{
	double d0,b0,temp;
	d0=(double)d;
	b0=(double)b;
	temp=sqrt(d0*d0-b0*b0);
	intervals[j].l=a-temp;
	intervals[j].r=a+temp;
	return 0;
}
int doit()
{
	int i,count=0;
	double right = intervals[0].r;//从左端点最小的区间开始,
	for(i = 1;i < n;i++)
	{
		if(right >=intervals[i].l)//如果下一个区间的左端点大于当前区间的右端点则这两个区间有公共区,则公用一台雷达
		{
			if(right>=intervals[i].r)
				right =intervals[i].r>right?right:intervals[i].r;//将right更改为公共区间的右端点
		}
		else//如果无公共区间,需增加雷达数量
		{
			count++;
			right = intervals[i].r;
		}
	}
	return ++count;
}
int cmp(const void *a,const void *b)
{
	interval  *a0,*b0;
	a0=(interval*)a;
	b0=(interval*)b;
	if(((a0)->l>(b0)->l))
		return 1;
	if(((a0)->l<(b0)->l))
		return -1;
	else return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值