UVA_10382
这个题目的数据好像还是比较厚道的,应该没有太刁难的数据。
实际上对于每个喷头我们算它能够喷到范围应该是按矩形去算的,因为多出来的那点弧和边之间是有空隙的。这样我们就能将喷头的喷洒范围转化成对应的区间,于是这个题目就变成了区间覆盖问题。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#define MAXD 10010
int N, L, W, r[MAXD], w[MAXD], x[MAXD];
double left[MAXD], right[MAXD];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p;
int *q = (int *)_q;
return left[*p] < left[*q] ? -1 : 1;
}
void init()
{
int i, j, k;
double ans;
for(i = 0; i < N; i ++)
{
scanf("%d%d", &x[i], &w[i]);
if(2 * w[i] <= W)
left[i] = right[i] = L + 1.0;
else
{
ans = sqrt((double)w[i] * w[i] - (double)W * W / 4);
left[i] = x[i] - ans;
right[i] = x[i] + ans;
}
}
for(i = 0; i < N; i ++)
r[i] = i;
qsort(r, N, sizeof(r[0]), cmp);
}
void solve()
{
int i, j, k, num = 0;
double a = 0, b = 0;
for(i = 0; i < N; i ++)
{
k = r[i];
if(left[k] > a)
{
if(b >= L || left[k] > b)
break;
a = b;
++ num;
if(right[k] > b)
b = right[k];
}
else if(right[k] > b)
b = right[k];
}
if(b >= L)
printf("%d\n", num + 1);
else
printf("-1\n");
}
int main()
{
while(scanf("%d%d%d", &N, &L, &W) == 3)
{
init();
solve();
}
return 0;
}