您的位置:首页 > 编程语言

nyoj 12 喷水装置二

2016-04-27 09:10 323 查看

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  学习 竞赛 编程