POJ 1328: Radar Installation

题目来源:http://poj.org/problem?id=1328

poj又开放啦,虽然noi还是不能提交

千万要注意stl::sort里面自定义比较运算时候的写法:一种是在类里面重载<运算符,一种是在类外定义全局函数comp,将函数名作为sort的第3个参数

方法一

struct intervial{
	double left,right;

	bool operator< (const intervial &b) const
	{
		return left<b.left;
	}

};

sort(vec.begin(), vec.end());

方法二

struct intervial{
	double left,right;	
};

bool comp (const intervial &a, const intervial &b)
{
	return a.left<b.left;
}

sort(vec.begin(), vec.end(), comp);

Radar Installation

Time Limit: 1000MS

Memory Limit: 10000K

Total Submissions: 103370

Accepted: 22969

Description

Assume the coasting is an infinite straightline. Land is in one side of coasting, sea in the other. Each small island is apoint locating in the sea side. And any radar installation, locating on thecoasting, can only cover d distance, so an island in the sea can be covered bya radius installation, if the distance between them is at most d. 

We use Cartesian coordinate system, defining the coasting is the x-axis. Thesea side is above x-axis, and the land side below. Given the position of eachisland in the sea, and given the distance of the coverage of the radarinstallation, your task is to write a program to find the minimal number ofradar installations to cover all the islands. Note that the position of anisland is represented by its x-y coordinates. 

 
Figure A Sample Input of Radar Installations

 

Input

The input consists of several test cases. Thefirst line of each case contains two integers n (1<=n<=1000) and d, wheren is the number of islands in the sea and d is the distance of coverage of theradar installation. This is followed by n lines each containing two integersrepresenting the coordinate of the position of each island. Then a blank linefollows to separate the cases. 

The input is terminated by a line containing pair of zeros 

Output

For each test case output one line consisting ofthe test case number followed by the minimal number of radar installationsneeded. "-1" installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 1

1 2
0 2

0 0

SampleOutput

Case 1: 2
Case 2: 1

Source

Beijing 2002

-----------------------------------------------------

解题思路

贪心算法。算法的大体思路是将岛屿通过雷达半径转化为x轴上的线段,寻找这些线段之间所有的相交部分。

1. 计算以岛屿为中心、雷达半径为半径的圆在x轴上的割线线段

2. 将线段按左端点升序排列,形成一个队列

3. 当队列非空,从队首取出一个线段,ans++. 该线段出队,记R=该线段的右端点

4. 当队列非空,从队首取出一个线段,如果该线段的左端点<=R,则出队,并维护RR取为R之前的值和此线段右端点的较小值

5. 循环执行4直到没有点出队或队列空,转3

-----------------------------------------------------

代码 

//Radar Installation
//Time Limit: 1000MS		Memory Limit: 10000K
//Total Submissions: 103356		Accepted: 22966
//Description
//
//Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d. 
//
//We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates. 
// 
//Figure A Sample Input of Radar Installations
//
//
//Input
//
//The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases. 
//
//The input is terminated by a line containing pair of zeros 
//Output
//
//For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.
//Sample Input
//
//3 2
//1 2
//-3 1
//2 1
//
//1 2
//0 2
//
//0 0
//Sample Output
//
//Case 1: 2
//Case 2: 1
//Source
//
//Beijing 2002

#include<iostream>
#include<fstream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;

struct intervial{
	double left,right;

	// 千万注意重载运算符的写法!!!
	bool operator< (const intervial &b) const
	{
		return left<b.left;
	}

};


int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin("1328.txt");
	int n,d,i,cnt=0;
	double x,y,l,r,R;
	deque<intervial> itv;
	int ans = 0;
	while (fin >> n >> d)
	{
		if (n==0)
		{
			break;
		}
		cnt++;
		itv.clear();
		ans = 0;
		
		for (i=0; i<n; i++)
		{
			fin >> x >> y;
			if (y>d)
			{
				ans = -1;
			}
			l = x-sqrt(d*d-y*y);
			r = x+sqrt(d*d-y*y);
			intervial iv;
			iv.left = l;
			iv.right = r;
			itv.push_back(iv);
		}

		if (ans != -1)
		{
			if (n==1)
			{
				ans = 1;
			}
			else
			{
				sort(itv.begin(), itv.end());			// 将线段按左端点升序排列
				while(!itv.empty())						// 当队列不空
				{
					intervial it = itv.front();			// 取队首元素
					itv.pop_front();					// 出队
					ans++;								// 结果+1
					R = it.right;						// 当前右边界R=该线段的右端点
					while (!itv.empty())				// 当队列不空
					{
						intervial iv = itv.front();		// 取队首元素
						if (R>=iv.left)					// 如果当前右边界在该线段左端点右侧,说明两线段右相交部分
						{
							itv.pop_front();			// 在相交部分建雷达就能覆盖该岛屿,不用为该岛屿新建雷达
							R = R<iv.right? R:iv.right;	// 维护R为相交部分的右边界
						}
						else
						{
							break;						// 如果没有相交部分就跳出循环
						}
					}
				}
			}
		}
		cout << "Case " << cnt << ": " << ans << endl;
	}
	fin.close();
#endif
#ifdef ONLINE_JUDGE
	int n,d,i,cnt=0;
	double x,y,l,r,R;
	deque<intervial> itv;
	int ans = 0;
	while (cin >> n >> d)
	{
		if (n==0)
		{
			break;
		}
		cnt++;
		itv.clear();
		ans = 0;
		
		for (i=0; i<n; i++)
		{
			cin >> x >> y;
			if (y>d)
			{
				ans = -1;
			}
			l = x-sqrt(d*d-y*y);
			r = x+sqrt(d*d-y*y);
			intervial iv;
			iv.left = l;
			iv.right = r;
			itv.push_back(iv);
		}

		if (ans != -1)
		{
			if (n==1)
			{
				ans = 1;
			}
			else
			{
				sort(itv.begin(), itv.end());
				while(!itv.empty())
				{
					intervial it = itv.front();
					itv.pop_front();
					ans++;
					R = it.right;
					while (!itv.empty())
					{
						intervial iv = itv.front();
						if (R>=iv.left)
						{
							itv.pop_front();
							R = R<iv.right? R:iv.right;
						}
						else
						{
							break;
						}
					}
				}
			}
		}
		cout << "Case " << cnt << ": " << ans << endl;
	}
	return 0;
#endif
}


猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/80581263