• nyoj-12-喷水装置(二)


    http://acm.nyist.net/JudgeOnline/problem.php?pid=12

    喷水装置(二)

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
    描述
    有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
    输入
    第一行输入一个正整数N表示共有n次测试数据。
    每一组测试数据的第一行有三个整数n,w,h,n表示共有n个喷水装置,w表示草坪的横向长度,h表示草坪的纵向长度。
    随后的n行,都有两个整数xi和ri,xi表示第i个喷水装置的的横坐标(最左边为0),ri表示该喷水装置能覆盖的圆的半径。
    输出
    每组测试数据输出一个正整数,表示共需要多少个喷水装置,每个输出单独占一行。
    如果不存在一种能够把整个草坪湿润的方案,请输出0。
    样例输入
    2 2 8 6 1 1 4 5 2 10 6 4 5 6 5
    样例输出
    1 2

    解题思路:类似于区间覆盖问题,和ZOJ1360比较相似-> http://www.cnblogs.com/angle-qqs/p/4073247.html

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <math.h>
     5 
     6 struct P{
     7     double x;
     8     double left, right;
     9 }p[1010];
    10 
    11 int cmp(const void *a, const void *b){
    12     struct P *c = (struct P *)a;
    13     struct P *d = (struct P *)b;
    14     return c->left > d->left ? 1 : -1;
    15 }
    16 
    17 int main(){
    18     int T, n, w, h, i, ans, flag;
    19     double r, dis, h1, sum, max;
    20     scanf("%d", &T);
    21     while(T--){
    22         scanf("%d %d %d", &n, &w, &h);
    23         h1 = 1.0 * h / 2.0;
    24         for(i = 0; i < n; i++){
    25             scanf("%lf %lf", &p[i].x, &r);
    26             if(r > h1){//当半径大于高的一半的时候
    27                 dis = sqrt((r * r) - (h1) * (h1));
    28                 p[i].left = p[i].x - dis;
    29                 p[i].right = p[i].x + dis;
    30             }
    31             else{
    32                 p[i].left = p[i].right = p[i].x;
    33             }
    34 
    35         }
    36         qsort(p, n, sizeof(p[0]), cmp);
    37 //        for(i = 0; i < n; i++){
    38 //            printf("%lf %lf ", p[i].left, p[i].right);
    39 //        }
    40         sum = 0;
    41         ans = 0;
    42         flag = 0;
    43         while(sum < w){//当覆盖长度小于宽的时候
    44             max = 0;
    45             for(i = 0; i < n && p[i].left <= sum; i++){//求当前最多覆盖
    46                 if(p[i].right - sum > max){
    47                     max = p[i].right - sum;
    48                 }
    49             }
    50             if((max - 0) < 1e-9){//如果不能连续覆盖
    51                 flag = 1;
    52                 break;
    53             }
    54             else{
    55                 sum += max;
    56                 ans++;
    57             }
    58         }
    59         if(flag == 1){
    60             printf("0 ");
    61         }
    62         else{
    63             printf("%d ", ans);
    64         }
    65     }
    66     return 0;

    67 } 

  • 相关阅读:
    MySQL的注入过程
    nmap 扫描器的功能
    用dvwa演示带有用户令牌(user_token)的暴力破解
    在python中安装requests模块
    如何发现struts2漏洞
    vs2017的主题颜色的配置
    在vs上开发linux c++
    linux主机之间的SSH链接
    verilog 实用的小技巧
    verilog 实现DDS
  • 原文地址:https://www.cnblogs.com/angle-qqs/p/4092998.html
Copyright © 2020-2023  润新知