HDU 2795 Billboard--线段树

http://acm.hdu.edu.cn/showproblem.php?pid=2795

题意:有一块板,规格为h*w,然后有n张海报,每张海报的规格为1*wi,选择贴海报的位置是:尽量高,同一高度,选择尽量靠左的地方。要求输出每张海报的高度位置。

输入的时候有一点优化的地方,就是如果h>n的时候,可以让h=n。因为一张海报的宽度不会超过版块的宽度,所以版块高度不用多于海报数量。否则的话会内存爆掉。

思路:

线段树存剩下的最大宽度,每次找到最大值的位子,然后减去x;

注意的地方:

在代码中有注释,因为那里wa了数次;一开始的时候是没有判断当前节点的最大值有没有比x大,如果在找到节点的那里再要在判断一下;

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define maxn 200100
 5 #define lson l,m,rt<<1
 6 #define rson m+1,r,rt<<1|1
 7 int Max[maxn<<2],w;
 8 int max(int a,int b)
 9 {
10     return a>b?a:b;
11 }
12 void Pushup(int rt)
13 {
14     Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
15 }
16 void build(int l,int r,int rt)
17 {
18     Max[rt]=w;
19     if(l==r)return ;
20     int m=(l+r)>>1;
21     build(lson);
22     build(rson);
23 }
24 int query(int x,int l,int r,int rt)
25 {
26     if(l==r)
27     {
28         if(Max[rt]<x)        //这个地方要判断一下,因为刚开始的时候是没有判断最大值有没有大于x的
29             return -1;
30         Max[rt]-=x;
31         return l;
32     }
33     int ret=-1;
34     int m=(l+r)>>1;
35     if(x<=Max[rt<<1])
36         ret=query(x,lson);
37     else if(x<=Max[rt<<1|1])
38         ret=query(x,rson);
39     Pushup(rt);
40     return ret;
41 }
42 int main()
43 {
44     int h,n,a;
45     while(~scanf("%d %d %d",&h,&w,&n))
46     {
47         if(h>n)
48             h=n;
49         build(1,h,1);
50         while(n--)
51         {
52             scanf("%d",&a);
53             printf("%d\n",query(a,1,h,1));
54         }
55     }
56     return 0;
57 }

 

posted on 2013-02-06 21:35  acoderworld  阅读(59)  评论(0)    收藏  举报

导航