zoukankan      html  css  js  c++  java
  • 区间完全覆盖问题(贪心)

    题目链接:here

    题意:在一个矩形的花坛上,中间水平放了一排喷水装置,浇灌半径为r,问最少需要多少个装置可以润湿整个花坛。

    将每个装置转换成一条线段,就变成了求最少的线段覆盖整个区间。

    将各线段左端点从小到大排序

    设已覆盖区间的右端点为ed

    每次贪心选择起点小于ed的线段中右端点最大的那一条,然后更新ed。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=50010;
     4 
     5 struct Seg{
     6     double x,y;
     7     bool operator < (const Seg& a)const{
     8         return x<a.x;
     9     }
    10 }s[maxn];
    11 
    12 int main(){
    13     int n;
    14     double l,w;
    15     int t;
    16     scanf("%d",&t);
    17     while(t--){
    18         scanf("%d%lf%lf",&n,&l,&w);
    19         double c,r;
    20         w/=2;
    21         for(int i=0;i<n;i++){
    22             scanf("%lf%lf",&c,&r);
    23             if(r<w) s[i].x=s[i].y=0;
    24             else{
    25                 double x=sqrt(r*r-w*w);
    26                 s[i].x=c-x;
    27                 s[i].y=c+x;
    28             }
    29         }
    30         sort(s,s+n);
    31         if(s[0].x>0){
    32             puts("0");
    33             continue;
    34         }
    35         int ans=0;
    36         double st=0,ed=0;
    37         for(int i=0;i<n;i++){
    38             if(s[i].x<=st){
    39                 while(i<n&&s[i].x<=st){
    40                     ed=max(ed,s[i].y);
    41                     i++;
    42                 }
    43                 i--;
    44                 ans++;
    45                 st=ed;
    46             }
    47             if(ed>=l) break;
    48         }
    49         if(ed>=l) printf("%d
    ",ans);
    50         else puts("0");
    51     }
    52 }
    View Code
  • 相关阅读:
    利用for循环 修改精灵图背景位置
    添加列表项 避免浏览器反复渲染 Fragment
    向元素添加属性名和属性值
    分割文本节点
    查询、回显 基本功能
    获取注释
    合并文本节点
    Node(节点)的4个操作方法
    setTimeout与setInterval
    javascript循环
  • 原文地址:https://www.cnblogs.com/yijiull/p/7445319.html
Copyright © 2011-2022 走看看