您的位置:首页 > 其它

hdu 2795 Billboard(线段树)

2015-05-29 11:19 387 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2795

题意:给一个h*w的广告牌,一个单位高度是一行,然后有一些公告贴上去,公告是1*wi的大小的长纸条,优先贴在左上方,如果空间不满足就输出-1,可以的话就输出位置(第几行)

类似的区间问题首先想到的是线段树。但是这里要以行数为着眼点,left是上行数,right是下行数,把wi设为结点内的一个数据成员。最后写出found子函数,水到渠成。

#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int w;
const int maxn=2e5+5;
struct node{
    int l,r,mid,length;
}d[3*maxn];
void build(int s,int e,int dex){
    d[dex].l=s;
    d[dex].r=e;
    d[dex].mid=(s+e)/2;
    d[dex].length=w;
    if(d[dex].l==d[dex].r)return ;
    build(s,d[dex].mid,dex*2);
    build(d[dex].mid+1,e,dex*2+1);
}
int found(int b,int dex){
    if(d[dex].l==d[dex].r){
        d[dex].length-=b;
        return d[dex].l;
    }
    int ans;
    if(b<=d[dex*2].length)ans=found(b,dex*2);
    else ans=found(b,dex*2+1);
    d[dex].length=max(d[dex*2].length,d[dex*2+1].length);
    return ans;
}
int main()
{
    //freopen("cin.txt","r",stdin);
    int h,n,i,board;
    while(~scanf("%d%d%d",&h,&w,&n)){
        build(1,min(h,n),1);
        for(i=0;i<n;i++){
            scanf("%d",&board);
            if(d[1].length<board)printf("-1\n");
            else printf("%d\n",found(board,1));
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: