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


    12-喷水装置(二)


    内存限制:64MB 时间限制:3000ms Special Judge: No
    accepted:10 submit:30

    题目描述:

    有一块草坪,横向长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

    分析:
      ①、因为是圆组合成一条线的问题所以我们应该清晰认识到的是 --> 圆在该区域的有效长度 L = (sqrt(r^2 - (h/2)^2))
      ②、因为圆的有效长度为L,所以半径小于 (h/2) 的圆完全没有考虑的必要了(酱紫:要考虑的圆将会减少一定的数量)

    步骤:
      ①、根据输入的位置坐标和半径情况构建出每个圆的有效区域,并将其存放在结构体中
      ②、从左到右遍历寻找一组这样的区域:“左端 小于 初始点” && “右端 大于 初始点” && “有端点的值最大”
      ③、将最大的右端点作为下一个初始点
      ④、循环 ②、③ 步,知道能够全部覆盖草坪或喷泉用完

    核心代码:
      
     1 double L_flag = 0, R_flag;
     2 for(int i = 0; i < n; ++ i)
     3 {
     4     if(P[i].l <= L_flag)
     5     {
     6         R_flag = P[i].r;
     7         while(P[i].l <= L_flag && i < n)
     8         {
     9             R_flag = max(P[i].r, R_flag);
    10             ++ i;
    11         }
    12         -- i;
    13         cnt ++;
    14         L_flag = R_falg;
    15     }
    16     if (L_flag >= w)
    17     {
    18         printf("%d
    ", cnt);
    19         break;
    20     }
    21 }

    C/C++代码实现(AC):
     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <queue>
     7 #include <set>
     8 #include <map>
     9 #include <stack>
    10 
    11 using namespace std;
    12 
    13 struct node
    14 {
    15     double l, r;
    16 } P[10010];
    17 
    18 bool cmp(node a, node b)
    19 {
    20     return a.l < b.l;
    21 }
    22 
    23 int main ()
    24 {
    25     int t;
    26     scanf("%d", &t);
    27     while (t --)
    28     {
    29         int cnt = 0, n, flag = 0;
    30         double w, h; // n 装置个数、 w长度、 h 高度
    31         scanf("%d%lf%lf", &n, &w, &h);
    32         for(int i = 0; i < n; ++ i)
    33         {
    34             double x, r, temp;
    35             scanf("%lf%lf", &x, &r);
    36             if (r > (h / 2))
    37             {
    38                 temp = sqrt(r * r - (h / 2) * (h / 2));
    39                 P[i].l = x - temp;
    40                 P[i].r = x + temp;
    41             }
    42             else
    43             {
    44                 P[i].l = x;
    45                 P[i].r = x;
    46             }
    47         }
    48         sort(P, P + n, cmp);
    49 
    50         double L_flag = 0.0, R_flag;
    51         for(int i = 0; i < n; ++ i)
    52         {
    53             if(P[i].l <= L_flag)
    54             {
    55                 R_flag = P[i].l;
    56                 while(P[i].l <= L_flag && i < n)
    57                 {
    58                     R_flag = max(R_flag, P[i].r);
    59                     ++ i;
    60                 }
    61                 -- i;
    62                 L_flag = R_flag;
    63                 cnt ++;
    64             }
    65             if(L_flag >= w)
    66             {
    67                 flag = 1;
    68                 printf("%d
    ", cnt);
    69                 break;
    70             }
    71         }
    72         if(!flag) printf("0
    ");
    73     }
    74     return 0;
    75 }
    
    
  • 相关阅读:
    struts2+hibernate+Spring分层开发
    (江苏大学)校园网上网帮助工具开发详解(附源码)【行政教学区】【城市热点】
    [CLR的执行模型].NET应用程序是如何执行的?
    ASP.NET服务器对于请求的处理过程
    【简单Web服务器搭建】基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
    ASP.NET 页生命周期和页面事件处理管道
    【分析总结】ASP.NET中的状态管理原理
    【CLRsos调试】关于方法表继承调用问题的总结
    【分析最原始验证码生成】HTTP请求处理程序
    [ASP.NET]Session在多个站点之间共享解决方案
  • 原文地址:https://www.cnblogs.com/GetcharZp/p/9048585.html
Copyright © 2020-2023  润新知