poj_1328 贪心

方法:贪心。

思路:对于每一个小岛,岸上的雷达位置都有一个固定范围,只有在这个范围内,才能监测到。假设小岛分别是i1,i2,..,in,对应的雷达范围是:(x1,y1),(x2,y2),...,(xn,yn),先对雷达范围按x排序,得到:

s1(x1',y1'),s2(x2',y2'),...,sn(xn',yn')。分析:如果s1和s2有交集[p1,p2],说明雷达在[p1,p2]任意位置即可,为了雷达尽可能少,应放在最右面,即p2(但此时要注意,如果x2'==y2',即该小岛到海岸线的垂直距离正好是d,则监测点必须在y2'处);如果没有交集,s1必须有个雷达,s2也必须有个雷达。以此类推,用一个变量right记录当前要建雷达的最右位置。

PS:又是一道用C++就AC,用G++就TLE的题。不懂原因。


#include<iostream>
#include<cmath>

using namespace std;

int n;
double d;
double island[1000][2];
double region[1000][2];
int res;

void qsort(int left,int right)
{
	if(left<right)
	{
		int i=left,j=right;
		double x=region[i][0],y=region[i][1];
		while(i<j)
		{
			while(i<j&&region[j][0]>=x)
			{
				j--;
			}
			if(i<j)
			{
				region[i][0]=region[j][0];
				region[i][1]=region[j][1];
				i++;
			}
			while(i<j&&region[i][0]<x)
			{
				i++;
			}
			if(i<j)
			{
				region[j][0]=region[i][0];
				region[j][1]=region[i][1];
				j--;
			}
		}
		region[i][0]=x;
		region[i][1]=y;
		qsort(left,i-1);
		qsort(i+1,right);
	}
}

void greedy()
{
	int i;
	double right=region[0][1];
	res=1;
	for(i=1;i<n;i++)
	{
		if(region[i][0]<=right)
		{
			right=(region[i][1]>right)?right:region[i][1];
		}
		else
		{
			res++;
			right=region[i][1];
		}
	}
}

int main()
{
	int i,flag,num=0,index=0;
	cin>>n>>d;
	while(n!=0&&d!=0)
	{
		index++;
		flag=0;
		for(i=0;i<n;i++)
		{
			cin>>island[i][0]>>island[i][1];
			if(island[i][1]>d || island[i][1]<0 || d<0)
			{
				flag=1;
			}
			region[i][0]=island[i][0]-sqrt(d*d-island[i][1]*island[i][1]);
			region[i][1]=island[i][0]+sqrt(d*d-island[i][1]*island[i][1]);
		}
		if(flag==1)
		{
			cout<<"Case "<<index<<": -1"<<endl;
			cin>>n>>d;
			continue;
		}
		qsort(0,n-1);
		greedy();
		cout<<"Case "<<index<<": "<<res<<endl;
		cin>>n>>d;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值