zoukankan      html  css  js  c++  java
  • hdoj 2795 Billboard【线段树区间最大值】

    Billboard

    Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 16023    Accepted Submission(s): 6770


    Problem Description
    At the entrance to the university, there is a huge rectangular billboard of size h*w (h is its height and w is its width). The board is the place where all possible announcements are posted: nearest programming competitions, changes in the dining room menu, and other important information.

    On September 1, the billboard was empty. One by one, the announcements started being put on the billboard.

    Each announcement is a stripe of paper of unit height. More specifically, the i-th announcement is a rectangle of size 1 * wi.

    When someone puts a new announcement on the billboard, she would always choose the topmost possible position for the announcement. Among all possible topmost positions she would always choose the leftmost one.

    If there is no valid location for a new announcement, it is not put on the billboard (that's why some programming contests have no participants from this university).

    Given the sizes of the billboard and the announcements, your task is to find the numbers of rows in which the announcements are placed.
     
    Input
    There are multiple cases (no more than 40 cases).

    The first line of the input file contains three integer numbers, h, w, and n (1 <= h,w <= 10^9; 1 <= n <= 200,000) - the dimensions of the billboard and the number of announcements.

    Each of the next n lines contains an integer number wi (1 <= wi <= 10^9) - the width of i-th announcement.
     
    Output
    For each announcement (in the order they are given in the input file) output one number - the number of the row in which this announcement is placed. Rows are numbered from 1 to h, starting with the top row. If an announcement can't be put on the billboard, output "-1" for this announcement.
     
    Sample Input
    3 5 5
    2
    4
    3
    3
    3
     
    Sample Output
    1
    2
    1
    3
     
    -1
     
    题意:
    有一个高h宽w的公告栏,现在要在上边贴N个1*W的公告。要求1,要在能够完全放下的区域贴公告。2,贴公告时遵循最上最左的原则。问你每张公告分别贴在第几行,若公告无法插入输出-1。
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAX 200010
    using namespace std;
    int Max[MAX<<2];
    void pushup(int o)
    {
    	Max[o]=max(Max[o<<1],Max[o<<1|1]);
    }
    void gettree(int o,int l,int r,int w)
    {
    	Max[o]=w;//每个初值都设为行长,然后根据输入的广告的长度相应的缩短 
    	if(l==r)
    		return ;
    	int mid=(l+r)>>1;
    	gettree(o<<1,l,mid,w);
    	gettree(o<<1|1,mid+1,r,w);
    	pushup(o);//维护区间最大值 
    }
    int find(int o,int l,int r,int v)
    {
    	if(l==r)
    	{
            Max[o]-=v;
            return l;//如果本行可以放下这个长度的广告 就输出当前所在的行数l 
    	}            //因为如果第一行不可以,下边的回溯会改变l的值 
    	int mid=(l+r)>>1;
    	int ans;
    	if(Max[o<<1]>=v)
    	    ans=find(o<<1,l,mid,v);
    	else 
    	    ans=find(o<<1|1,mid+1,r,v);
    	pushup(o);
    	return ans;
    }
    int main()
    {
    	int h,n,i,j,a,w;
    	while(scanf("%d%d%d",&h,&w,&n)!=EOF)
    	{
    		int x=min(h,n);//建树时行数应当是刚好,如果取最大值,那么不管怎么放都可以放完
    		gettree(1,1,x,w);
    		while(n--)
    		{
    			scanf("%d",&a);
    			if(Max[1]<a)//Max[1]表示整棵树上的最大值 
    			    printf("-1
    ");
    			else
    			    printf("%d
    ",find(1,1,x,a));
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    registration system(map+思维)
    Codeforces 158B:Taxi(贪心)
    牛客小白月赛24 B-组队(二分)
    CF58C Trees(逆向思维)
    lower_bound和upper_bound学习笔记
    POJ--2689Prime Distance(区间素数筛)
    Codeforces Round #635 (Div. 2)
    navicat premium安装,使用
    Oracel 之PL/SQL Developer使用
    PLSQL,sql语句中带有中文的查询条件查询不到数据
  • 原文地址:https://www.cnblogs.com/tonghao/p/4808875.html
Copyright © 2011-2022 走看看