uva10382 - Watering Grass(区间覆盖变形)

题目:uva10382 - Watering Grass(区间覆盖变形)


题目大意:要给一片草坪浇水,给定草坪的长度和宽度,给出每个喷头的圆心C和喷水的半径R,问最少要几个喷头可以给整片草坪都浇上水。


解题思路:区间覆盖问题的变形,因为草坪有宽度W,所以这个每个喷头的有效范围是[C- sqrt(R* R - 0.25 * W * W   ,  C + sqrt (R*R - 0.25 * W *W)].


代码:

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;

const int N = 10005;
int n, l, w;
int visit[N];

double Max (const double a, const double b) { return a > b ? a: b; }

struct Len {
	
	double L, R;	
}len[N];

int cmp (const Len &a, const Len &b) { return a.L < b.L;}

void handle (int c, int r, int i) {
	
	double r1 = r;
	double c1 = c;
	double w1 = w;
	double temp = sqrt (r1 * r1 - 0.25 * w1 * w1);
	len[i].L = c - temp;
	len[i].R = c + temp;
}

int solve () {
	
	memset (visit, 0, sizeof (visit));
	if (len[0].L > 0)
		return -1;
	double s = 0;
	double ll = -1;
	int m = -1;
	for (int i = 0; i < n; i++) {
		
		if (len[i].L <= s) {
			
			if (ll < len[i].R) {

				visit[i] = 1;
				if (m >= 0)
					visit[m] = 0;
				m = i;
				ll = Max (ll, len[i].R);
			}
		} else {
			
			if (s == ll)
				return -1;
			s = ll;
			i--;
			m = -1;
		}
//		printf ("%f\n", ll);
	}
//	printf ("%f\n", ll);
	if (ll < l)
		return -1;
	int count = 0;
	for (int i = 0; i < n; i++)
		if (visit[i])
			count++;
	return count;
}

int main () {
	
	int c, r;
	while (scanf ("%d%d%d", &n, &l, &w) != EOF) {

		for (int i = 0; i < n; i++) {

			scanf ("%d%d", &c, &r);
			handle (c, r, i);
		}
		sort (len, len + n, cmp);
		
/*		for (int i = 0; i < n; i++)
			printf ("%f %f\n", len[i].L, len[i].R);*/
		printf ("%d\n", solve());

	}
	return 0;
}


你可能感兴趣的:(uva10382 - Watering Grass(区间覆盖变形))