zoukankan      html  css  js  c++  java
  • [POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线

    Description 

    Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to retire by the end of the year. The Goldmine management would like to reward him in acknowledgment of his conscientious work. As a reward Byteman may receive a small lot - a rectangular piece of the mine's area with sides of length s and w parallel to the axes of the coordinate system. He may choose the location of the lot. Of course, a value of the lot depends on the location. The value of the lot is a number of gold nuggets in the area of the lot (if a nugget lies on the border of the lot, then it is in the area of the lot). Your task is to write a program which computes the maximal possible value of the lot (the value of the lot with the best location). In order to simplify we assume that the terrain of the Goldmine is boundless, but the area of gold nuggets occurrence is limited. 

    Task
    Write a program which:

    1.reads the location of gold nuggets, 
    2.computes the maximal value of a lot (i.e. the maximal number of gold nuggets on the lot of given size), 
    3.writes the result . 
    Input 

    In the first line there are two positive integers s and w separated by a single space, (1<=s,w<=10 000); they denote the lengths of lot's sides - parallel to the OX-axe and OY-axe respectively. There is one positive integer n written in the second line, (1<=n<=15 000). It denotes the number of nuggets in the area of the Goldmine. In the following n lines there are written the coordinates of the nuggets. Each of these lines consists of two integers x and y, (-30 000<=x,y<=30 000), separated by a single space and denoting the x and the y coordinate of a nugget respectively.

    Output 

    The out should contain exactly one integer equal to the value of the most valuable lot of a given size.

    Sample Input 

    1 2
    12
    0 0
    1 1
    2 2
    3 3
    4 5
    5 5
    4 2
    1 4
    0 5
    5 0
    2 3
    3 2

    Sample Output 

    4



    题目大意

    给定二维平面上的N个点,寻找一个w*s(高w宽s,被这个点坑好久)的矩形,使得当中包括最多的点。

    上海邀请赛B题的题意和这一题类似。



    思路

    黑书原题。

    将每个点看作是两个事件从左到右进行扫描(能够维护队列控制队头和队尾的差不超过宽度,也能够依照时间顺序排序后进行处理),每个点抽象成长度为矩形高度的线段,线段经过次数最多的点便是结果。

    这样就把O(n^2)降维至O(n*log(A)),A为点纵坐标的范围。

    在这里能够提交

    http://acm.cs.ecnu.edu.cn/problem.php?problemid=1350

    ps:太弱了,不仅当场没出这道题并且后来做的时候还W一天,基础还是有待夯实啊。
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cmath>
    #include <map>
    #include <vector>
    #include <cstring>
    using namespace std;
    struct node{
        int t,pos,st;
    }ha[200000];
    int x1,x2,v;
    int _max;
    int n,w,h;
    int cmp(node x,node y)
    {
        return (x.t<y.t);//依照时间先后顺序排序,先删除点再加入点
    }
    int maxv[400000],addv[400000];
    void maintain(int o,int L,int R)
    {
        int lc=o<<1;
        int rc=lc+1;
        maxv[o]=0;
        if (R>L)
        {
            maxv[o]=max(maxv[lc],maxv[rc]);
        }
        maxv[o]+=addv[o];
    }
    void update(int o,int L,int R)
    {
        int lc=o<<1;
        int rc=lc+1;
        if (x1<=L&&x2>=R) addv[o]+=v;
        else {
            int M=L+(R-L)/2;
            if (x1<=M) update(lc,L,M);
            if (x2>M) update(rc,M+1,R);
        }
        maintain(o,L,R);
    }
    void query(int o,int L,int R,int add)
    {
        int lc=o<<1;
        int rc=lc+1;
        if (x1<=L&&x2>=R) _max=max(_max,maxv[o]+add);
        else {
            int M=L+(R-L)/2;
            if (x1<=M) query(lc,L,M,addv[o]+add);
            if (x2>M) query(rc,M+1,R,addv[o]+add);
        }
    }
    int main()
    {
        while(~scanf("%d%d%d",&w,&h,&n))
        {
            memset(maxv,0,sizeof(maxv));
            memset(addv,0,sizeof(addv));
            _max=0;
            int o,p,pt=0;
            memset(ha,0,sizeof(ha));
            for (int i=1;i<=n;i++)
                {
                    scanf("%d%d",&o,&p);
                    ha[++pt].t=o;
                    ha[pt].pos=p+30001;
                    ha[pt].st=1;
                    ha[++pt].t=o+w+1;
                    ha[pt].pos=p+30001;
                    ha[pt].st=-1;
                }
            sort(ha+1,ha+pt+1,cmp);//将全部时间点排序
            for (int i=1;i<=pt;i++)
            {
                x1=ha[i].pos;
                x2=ha[i].pos+h;
                x2=min(x2,60001);
                v=ha[i].st;
                update(1,1,60001);//更新点数
                if (ha[i].t!=ha[i+1].t||i==pt)//直至同一时间点的全部更新完毕之后才输出
                    {
                     x1=1;
                     x2=60001;
                     query(1,1,60001,0);
                    }
            }
            printf("%d
    ",_max);
        }
    }
    



  • 相关阅读:
    败家MM
    Lucene.Net
    罗氏制药事件
    关于request编码的问题
    昨天做了个站内全文搜索
    有时间研究 ror框架,ProMesh.NET: 开源的.net MVC框架
    DotLucene搜索引擎Demo之:创建索引
    超低密度SiO2气凝胶的制备及成型研究
    使用System.out.print/prilntln() 输出时存在的问题
    对C++对象实例化的测试
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4024420.html
Copyright © 2011-2022 走看看