poj 1328 Radar Installation 贪心

题意:给出岛屿个数n和地雷的范围c,然后再给出n个岛屿的xy坐标,在x轴上放置地雷,求出能覆盖所有岛屿的地雷最小数

    否则输出-1

 

思路:1、一开始,我第一个想法就是对岛屿进行排序,x从小到大,接着在x轴上放置地雷,尽可能靠右边并且能够覆盖左边的岛屿

    ,接着筛选右边同时也处于该地雷之内的岛屿,再不断找左边第一个没有地雷覆盖的岛屿继续放置最右边的地雷。。。

    然后WA了。

 

    2、网上的普遍做法,就是对每个岛屿计算能够覆盖到他的地雷范围,然后题目就变成区间的最少覆盖问题了,我就用这种

    算法做了,最终还是AC了。

 

 

AC代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAX_N = 1005;
int n, _case,d;
double u,v;
bool vis[MAX_N];
struct node{
	double x,y;
}w[MAX_N];

int cmp(node n1, node n2)
{
	if(n1.x == n2.x) return n1.y > n2.y;
	else return n1.x < n2.x;
}

void solve()
{
	sort(w,w+n, cmp);
	
///	for(int i = 0; i < n; i++)
//		cout<<w[i].x<<' '<<w[i].y<<endl;
	
	int ans = 1;
	double right = w[0].y;
	
	for(int i = 1; i < n; i++)
	{
		if(w[i].x > right)
		{
			ans ++;
			right = w[i].y;
		}else
		{
			if(w[i].y < right)
				right = w[i].y;
		}
	}
	printf("%d\n", ans);
}

int main()
{
	//freopen("in.txt", "r", stdin);
	_case = 1;
	while(cin>>n>>d && (n || d))
	{
		bool flag = false;
		
		for(int i = 0; i < n; i++)
		{
			scanf("%lf %lf", &u, &v);
			//cin>>u>>v;
			double dist = sqrt(1.0*d*d - v*v);
			w[i].x = u - dist;
			w[i].y = u + dist;
			
			if(fabs(v) > d) flag = true;
		}
		printf("Case %d: ", _case++);
		if(flag) puts("-1");
		else solve();
	}
	return 0;
}
posted @ 2016-04-26 10:48  sevenun  阅读(144)  评论(0编辑  收藏  举报