zoukankan      html  css  js  c++  java
  • 题解报告——窗口的星星

    题目背景

    小卡买到了一套新房子,他十分的高兴,在房间里转来转去。

    题目描述

    晚上,小卡从阳台望出去,“哇~~~~好多星星啊”,但他还没给其他房间设一个窗户,天真的小卡总是希望能够在晚上能看到最多最亮的星星,但是窗子的大小是固定的,边也必须和地面平行。这时小卡使用了超能力(透视术)知道了墙后面每个星星的位置和亮度,但是小卡发动超能力后就很疲劳,只好拜托你告诉他最多能够有总和多亮的星星能出现在窗口上。

    输入输出格式

    输入格式:

    本题有多组数据,第一行为T 表示有T组数据T<=10

    对于每组数据

    第一行3个整数n,W,H,(n<=10000,1<=W,H<=1000000)表示有n颗星星,窗口宽为W,高为H。

    接下来n行,每行三个整数xi,yi,li 表示星星的坐标在(xi,yi),亮度为li。(0<=xi,yi<2^31)

    输出格式:

    T个整数,表示每组数据中窗口星星亮度总和的最大值。

    输入输出样例

    输入样例#1:
    2
    3 5 4
    1 2 3
    2 3 2
    6 3 1
    3 5 4
    1 2 3
    2 3 2
    5 3 1
    
    输出样例#1:
    5
    6
    

    说明

    小卡买的窗户框是金属做的,所以在边框上的不算在内。


    【思路分析】

    看到这道题其实还是懵了一会儿,这是计算几何???,很明显不可做嘛,正打算跳题,旁边的大佬就提醒了一句,这不是计算几何,好嘛,那就再看看呗,突然发现,难道不可以用前不久刚学的扫描线来gank一波吗。

    没错扫描线!!!可有人可能会问了,这道题全是点,哪来的线给你扫啊,很好,这就是这道题的关键了。

    我们使用矩形去框这些星星们,但是我们为何不把星星转换成一个矩形呢,假设每个星星都可以几万W地放光,那些光不就可以看作一个区域了吗?!!

    我们假设以星星所在点的位置看作发光区域的左下角,发光区看作一个和窗户一样高,宽的矩形,那我们只需要统计最多一个地方有多少个矩形重叠就行了。。。

    是不是一下就舒服了很多,回归到了我们美妙的扫描线了!!!

    【注意事项】

    这道题叙述的边框不能看到星星,这是一个很坑的,要多加注意判断,个人认为,题目都很恶心了,还要一个这么扯淡的条件,很烦的!!!

    还有就是多组数据!!!必须要在每次建线段树的时候注意清空,答案也要赋初值,不然就要和我一样,一直爆10分,也不知道为什么。。。

    【代码实现】

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 struct edge{
      7     int h,lx,rx,s;
      8 }line[20005];
      9 struct sd{
     10     int son[2],l,r,len,s;
     11 }t[40005];
     12 int X[20005];
     13 int cnt;
     14 bool cmp(edge a,edge b)
     15 {
     16     if(a.h==b.h) return a.s>b.s;
     17     return a.h<b.h;
     18 }
     19 void build(int &v,int l1,int r1)
     20 {
     21     cnt++;v=cnt;
     22     t[v].l=l1,t[v].r=r1,t[v].len=0,t[v].s=0;
     23     if(l1==r1) return;
     24     int mid=(l1+r1)>>1;
     25     build(t[v].son[0],l1,mid);
     26     build(t[v].son[1],mid+1,r1);
     27 }
     28 int find(int l1,int r1,int key)
     29 {
     30     while(l1<=r1)
     31     {
     32         int mid=(l1+r1)/2;
     33         if(X[mid]==key) return mid;
     34         else
     35         if(X[mid]<key) l1=mid+1;
     36         else r1=mid-1;
     37     }
     38 }
     39 void pushup(int v)
     40 {
     41     t[v].len=max(t[t[v].son[0]].len,t[t[v].son[1]].len);
     42 }
     43 void pushdown(int v)
     44 {
     45     if(t[v].s==0) return;
     46     if(t[v].l!=t[v].r)
     47     {
     48         int ls=t[v].son[0],rs=t[v].son[1];
     49         t[ls].s+=t[v].s;
     50         t[ls].len+=t[v].s;
     51         t[rs].s+=t[v].s;
     52         t[rs].len+=t[v].s;
     53     }
     54     t[v].s=0;
     55 }
     56 void update(int v,int l1,int r1,int c)
     57 {
     58     pushdown(v);
     59     if(t[v].l==l1&&t[v].r==r1)
     60     {
     61         t[v].len+=c;
     62         t[v].s+=c;
     63         pushdown(v);
     64         return;
     65     }
     66     int mid=(t[v].l+t[v].r)>>1;
     67     if(r1<=mid) update(t[v].son[0],l1,r1,c);
     68     else
     69     if(l1>mid) update(t[v].son[1],l1,r1,c);
     70     else
     71     {
     72         update(t[v].son[0],l1,mid,c);
     73         update(t[v].son[1],mid+1,r1,c);
     74     }
     75     pushup(v);
     76 }
     77 int main()
     78 {
     79     int T;
     80     scanf("%d",&T);
     81     while(T--)
     82     {
     83         cnt=0;
     84         int n,W,H;
     85         scanf("%d%d%d",&n,&W,&H);
     86         for(int i=1;i<=n;i++)
     87         {
     88             int x1,y1,val;
     89             scanf("%d%d%d",&x1,&y1,&val);
     90             line[i].lx=x1,line[i].rx=x1+W-1,line[i].h=y1,line[i].s=val;
     91             X[i]=x1;
     92             line[i+n].lx=x1,line[i+n].rx=x1+W-1,line[i+n].h=y1+H-1,line[i+n].s=-val;
     93             X[i+n]=x1+W-1;
     94         }
     95         sort(X+1,X+1+n*2);
     96         sort(line+1,line+1+n*2,cmp);
     97         int k=0;X[n*2+1]=-1;
     98         for(int i=1;i<=n*2;i++)
     99         {
    100             if(X[i]!=X[i+1])
    101             {
    102                 k++;X[k]=X[i];
    103             }
    104         }
    105         int root=0;
    106         build(root,1,k);
    107         int res=0;
    108         for(int i=1;i<=n*2;i++)
    109         {
    110             int ll=find(1,k,line[i].lx);
    111             int rr=find(1,k,line[i].rx);
    112             
    113             update(1,ll,rr,line[i].s);
    114             res=max(res,t[1].len);
    115         }
    116         printf("%d
    ",res);
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    网络安全分析
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1540 机器
    java实现 洛谷 P1540 机器
  • 原文地址:https://www.cnblogs.com/genius777/p/8645181.html
Copyright © 2011-2022 走看看