贪心——POJ1328

POJ1328



/*

****************************************************************
算法原理:
1)以海岛(x,y)为圆心,覆盖范围dist为半径画圆,则与x轴存在
①0个交点:y>dist的情况,case输出为-1;
②2个交点:得到x轴范围区间(left,right);
由三角形勾股定理得:left= x-sqrt(dist*dist - y*y);
					right=x+sqrt(dist*dist - y*y);
③1个交点:left=right情况,不另做处理;

2)如果岛1(left1,right1)与岛2(left2,right2)
有交集(经过排序):表明岛1与岛2可以共用一个radar;
否则:radar+1;

3)我们把岛1看成不断吞并岛2(即以left的大小排序后的next)区间的
怪兽,岛1的right与岛2的left比较:
if (岛1的right < 岛2的left)  ; radar++; 岛1的right=岛2的right;
if (岛1的right < 岛2的right) ; 岛1的right=岛2的right;

****************************************************************
实现:
1)初始化island结构体,用于记录岛屿坐标
   x_cord结构体,即为x轴区间(left,right)
2)while外循环,只有当输入0,0时才退出。
   动态分配内存,for内循环保存海岛坐标位置
3)计算区间,使用lambda表达式以left的值sort(n个区间)
4)同样用for循环,更新区间

Notice:最后偷懒没有按题目要求的输出格式输出 :D

****************************************************************

*/


#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>

using namespace std;

struct island						//记录一个case的岛屿情况
{
	int x;
	int y;
};
struct x_cord						//记录一个case的区间情况
{
	double left;
	double right;
};
vector<x_cord> x_pos;
int main()
{
	int count = 0, radar = 0;
	while (1)
	{
		int n, dist;
		radar = 1, count++;		//radar每次需要重新计数,count则是累加的
		cin >> n >> dist;
		if (!(n&&dist))			//n!=0&&dist!=0
			break;
		island* pos = new island[n];

		for (int i = 0; i < n; i++)
		{	
			cin >> pos[i].x >> pos[i].y;
			if (dist < pos[i].y)
			{
				cout << "Case  " << count << ":  " << -1 << endl;
				return 0;
			}
			
			x_cord temp;
			double d = sqrt(dist*dist - pos[i].y*pos[i].y);
			temp.right = pos[i].x + d;
			temp.left = pos[i].x - d;
			x_pos.push_back(temp);
		}
		sort(x_pos.begin(), x_pos.end(),
				[](x_cord m,x_cord n) {return m.left<n.left; });	//lambda表达式对左区间排序

		double rightside = x_pos.at(0).right;
		for (int i = 1; i < n; i++)
		{
			if (x_pos.at(i).left>rightside)					
			{
				radar++;
				rightside = x_pos.at(i).right;
			}
			if (x_pos.at(i).right>rightside)						// 如果是next.right<current.left,就不更新区间
			{
				rightside = x_pos.at(i).right;
			}
		}
		cout << "Case  " << count << ":  " << radar << endl;
	}
		
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值