void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

给出一个广告牌大小,给出n个广告的长度,每个广告高度占一行,按照顺序尽量安排广告在靠左上角位置

问,每次给出一个广告长度,求出在哪一行?

很难想到线段树啊。。。。把行数给建树了,val维护当前区间的行内某行最大的空位数,然后安排的时候,优先左树去用

有点类似二分了。。。。

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
using namespace std;
const int MAX = 200010;
struct Tnode{ int l,r,val;};
Tnode node[MAX<<2];
void init()
{
	memset(node,0,sizeof(node));

}

void build(int t,int l,int r,int w)//val存放当前最大的空位值
{
	node[t].l = l; node[t].r = r;
	node[t].val = 0;
	if( node[t].l == node[t].r - 1 )
	{
	   node[t].val=w ;
	   return;
	}
	int mid = MID(l,r);
	build(L(t),l,mid,w);
	build(R(t),mid,r,w);
	node[t].val=max(node[L(t)].val,node[R(t)].val);
}
int update(int t,int wh)
{
    int ans;
    if(node[t].val<wh)return -1;
    if( node[t].l == node[t].r - 1 && node[t].val >= wh)
    {
        node[t].val -= wh;
        return node[t].l;
    }
    if(wh<=node[L(t)].val)
    ans=update(L(t),wh);
    else if(wh<=node[R(t)].val)
    ans= update(R(t),wh);
    node[t].val=max(node[L(t)].val,node[R(t)].val);
    return ans;
}
int main()
{
    int h,w,n,wh,ans;
    while(~scanf("%d%d%d",&h,&w,&n))
    {
        init();
        build(1,1,min(h,n)+1,w);
        //printf("%d\n",node[1].val);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&wh);
            ans=update(1,wh);
            //if(ans>h)ans=-1;
            printf("%d\n",ans);
        }
    }
}
posted on 2011-08-08 00:34  void-man  阅读(343)  评论(1)    收藏  举报