HDU 2795 Billboard 解题报告

题意:给定一个h*w广告牌,给定n个1*wi 的公告,贴公告的规则是,如果上面能贴尽量往上面贴,如果如果左边能贴尽量往左边贴,问你每个广告牌所在的行数;

解题思路,对n建树,然后动态维持区间最大值,查找更新!

解题代码:

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #define MAXN  200005
 6 struct node
 7 {
 8   int left ,right ,mid;
 9   long long  num;
10 }tree[4*MAXN];
11 int h , w,  n ;
12 int L(int c)
13 {
14    return 2*c ;
15 }
16 int R(int c )
17 {
18     return 2*c + 1;
19 }
20 void up(int c)
21 {
22     tree[c].num = tree[L(c)].num >tree[R(c)].num ?tree[L(c)].num :tree[R(c)].num;
23 }
24 void build(int c , int p , int v )
25 {
26   tree[c].left = p ;
27   tree[c].right = v ;
28   tree[c].mid = (p+v)/2;
29   tree[c].num = 0 ;
30   if(p == v)
31   {
32      tree[c].num = w ;
33      return;
34   }
35   build(L(c),p,tree[c].mid);
36   build(R(c),tree[c].mid+1,v);
37   up(c);
38 }
39 int ok = 0 ;
40 void F(int c, int value )
41 {
42    if(tree[c].num >= value )
43    {
44       //printf("%d
",tree[c].left);
45       if(tree[c].left == tree[c].right)
46       {
47          ok = tree[c].left;
48          tree[c].num -= value ;
49          return ;
50       }
51       if(tree[L(c)].num >= value )
52        F(L(c),value);
53       else
54        F(R(c),value);
55       up(c);
56    }
57 }
58 
59 
60 int main()
61 {
62   while(scanf("%d %d %d",&h,&w,&n) != EOF )
63   {
64     if(n >h )
65       build(1,1,h);
66     else
67       build(1,1,n);
68     for(int i = 1; i <= n;i ++)
69     {
70       int value ;
71       scanf("%d",&value);
72       ok = 0 ;
73 
74       F(1,value);
75       if(ok != 0 )
76         printf("%d
",ok);
77       else
78         printf("-1
");
79     }
80   }
81   return 0 ;
82 }
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3223233.html