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) 收藏 举报
浙公网安备 33010602011771号