zoukankan      html  css  js  c++  java
  • [HDOJ5091]Beam Cannon(贪心,线段树,扫描线,矩形内覆盖最多点)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5091

    题意:给个W*H的矩形和n个点,问这个矩形最多能框住多少个点。

    将每一个点(x,y)扩展为(x,y)、(x+W,y+H)的矩形跑扫描线。

    变成了一个区间累加更新,查询最值的问题。

    这个画画图就能想出来,因为贪心地想,一定是把一个点放到矩形的角上再向周围框,能框到最多。所以就利用了这一条贪心性质。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define lrt rt << 1
     5 #define rrt rt << 1 | 1
     6 typedef struct Seg {
     7     int add, val;
     8 }Seg;
     9 typedef struct Event {
    10     int l, r, h, sign;
    11 }Event;
    12 const int maxn = 40200;
    13 int n, w, h, ret;
    14 int hh[maxn], hcnt;
    15 vector<Event> event;
    16 Seg seg[maxn<<2];
    17 
    18 bool cmp(Event a, Event b) {
    19     if(a.h != b.h) return a.h < b.h;
    20     return a.sign > b.sign;
    21 }
    22 
    23 void build(int l, int r, int rt) {
    24     seg[rt].val = seg[rt].add = 0;
    25     if(l == r) return;
    26     int mid = (l + r) >> 1;
    27     build(l, mid, lrt);
    28     build(mid+1, r, rrt);
    29 }
    30 
    31 
    32 void pushup(int rt) {
    33     seg[rt].val = max(seg[lrt].val, seg[rrt].val);
    34 }
    35 
    36 void pushdown(int rt) {
    37     if(seg[rt].add) {
    38         seg[lrt].add += seg[rt].add;
    39         seg[lrt].val += seg[rt].add;
    40         seg[rrt].add += seg[rt].add;
    41         seg[rrt].val += seg[rt].add;
    42         seg[rt].add = 0;
    43     }
    44 }
    45 
    46 void update(int L, int R, int sign, int l, int r, int rt) {
    47     if(L <= l && r <= R) {
    48         seg[rt].add += sign;
    49         seg[rt].val += sign;
    50         return;
    51     }
    52     pushdown(rt);
    53     int mid = (l + r) >> 1;
    54     if(L <= mid) update(L, R, sign, l, mid, lrt);
    55     if(mid < R) update(L, R, sign, mid+1, r, rrt);
    56     pushup(rt);
    57 }
    58 
    59 int id(int x) {
    60     return lower_bound(hh, hh+hcnt, x) - hh + 1;
    61 }
    62 
    63 int main() {
    64     // freopen("in", "r", stdin);
    65     int x, y;
    66     while(~scanf("%d",&n) && n >= 0) {
    67         scanf("%d%d",&w,&h);
    68         event.clear(); hcnt = 0;
    69         for(int i = 0; i < n; i++) {
    70             scanf("%d%d",&x,&y);
    71             event.push_back(Event{x, x+w, y, 1});
    72             event.push_back(Event{x, x+w, y+h, -1});
    73             hh[hcnt++] = x, hh[hcnt++] = x + w;
    74         }
    75         sort(event.begin(), event.end(), cmp);
    76         sort(hh, hh+hcnt); hcnt = unique(hh, hh+hcnt) - hh;
    77         build(1, hcnt, 1);
    78         ret = 0;
    79         for(int i = 0; i < event.size(); i++) {
    80             int l = id(event[i].l);
    81             int r = id(event[i].r);
    82             int sign = event[i].sign;
    83             update(l, r, sign, 1, hcnt, 1);
    84             ret = max(ret, seg[1].val);
    85         }
    86         printf("%d
    ", ret);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    【转】Geary's C
    ArcGIS中影像与影像,影像与点云之间的配准
    [转] EPSG CODE的含义
    地图投影
    【从翻译mos文章】oracle linux 和外部存储系统 关系
    找呀志_使用SQLiteDatabase增删改提供的搜索方法和事务
    [049] 微信公众平台视频公开课1说话-基础知识
    我看到西电通院考试——学生应该做的事情?
    使用 Eclipse 的 SVN 主要插件创建项目/支/标签
    【SSH三个框架】Hibernate第十篇基础:inverse属性具体解释
  • 原文地址:https://www.cnblogs.com/kirai/p/6814173.html
Copyright © 2011-2022 走看看