ac了
1556017 PandaLHC 喷水装置(二) Accepted 4 472 C/C++ 04-27 08:58:34
贴上代码
这种思路比较笨 所以代码比较多
获取到每个喷水装置的左右交点之后,按左交点升序排序,然后在满足覆盖当前左边界boundary的情况下,找到右交点最大的喷水装置
然后更新边界,继续查找。
大家有更好的实现方式可以贴上来 一起学习
# include <stdio.h>
# include <math.h>
# include <stdlib.h>
# include <string.h>
#define MAX 10010
struct point{
double left;
double right;
};
point array[MAX];
//这里排序一级就好 二级排序之后做出来始终有问题 右边界直接后面循环找到最大即可
int cmp(const void *a ,const void * b)
{
struct point *c = (point *)a;
struct point *d = (point *)b;
return c->left - d->left;
}
int main()
{
int N, n, w, h;
int x, r, count, flag, last;
double boundary;
freopen("in.txt", "r", stdin);
scanf("%d", &N);
while(N--){
scanf("%d %d %d", &n, &w, &h);
boundary = 0.0;
count = 0;
last = 0;
for(int i = 0; i < n; i++){
scanf("%d %d", &x, &r);
if(r <= h / 2) continue;
//计算左右交点
array[i].left = x - sqrt( r * r - h * h / 4);
array[i].right = x + sqrt( r * r - h * h / 4);
}
qsort(array, n, sizeof(array[0]), cmp);
flag = 1;
//遍历数组查找右边界最大的可行解
//这里这个i = last 很有必要 不加上这个会不必要的去遍历很多重复数据 没加之前时间是8 加了是4
while(boundary < w){
double j = 0;
for(int i = last; array[i].left <= boundary && i < n; i++){
//在满足覆盖的条件下找到最大右边界的喷水装置
if(array[i].right - boundary >= j){
j = array[i].right - boundary;
last = i;
}
}
if(j == 0){
flag = 0;
break;
}
boundary += j;
count++;
}
if(!flag) printf("0\n");
else
printf("%d\n", count);
}
return 0;
}