• HDU 2795


    题目链接:

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

    题目大意:

      给定一个h * w大小的黑板报,h为黑板报的高,w为黑板报的宽。现在要贴上很多张海报,每张海报的大小为1 * m,m就是输入的海报宽度。从左上贴起,每次从上到下看有没有足够的空间贴海报,有就贴上。给定一组输入表示海报的宽度,输出每个海报贴的高度位置,若没得贴就输出-1。

    解题思路:

      一开始根本不知道怎么用线段树,看了题解之后才知道其模型其实很简单,构建一个大小等于海报数量的线段树,即表明每张海报贴一行就是了。然后维护的就是线段树左右子树的最大长度,这也很好理解,比如要贴的海报大小为a,如果线段树第一个节点值大于等于a,那么说明在线段树中有那么一个节点的剩余宽度大于a,也就是这一行可以贴这张海报。如果线段树第一个节点值小于a,那么说明这个黑板报的最大剩余宽度不足a,明显没法贴了。所以其实分析之后就是一个维护左右子节点最大值的线段树而已。

    代码:

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <map>
     6 #include <vector>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 #define ll long long
    11 #define INF 0x3f3f3f3f
    12 #define LL_INF 0x3f3f3f3f3f3f3f3f
    13 #define lson l, m, rt << 1
    14 #define rson m + 1, r, rt << 1|1
    15 #define MAX 200200
    16 
    17 int h, w;
    18 int maxn[MAX << 2];
    19 
    20 void pushUp(int rt)
    21 {
    22     maxn[rt] = max(maxn[rt << 1], maxn[rt << 1|1]);
    23 }
    24 
    25 void build(int l, int r, int rt)
    26 {
    27     if (l == r) {
    28         maxn[rt] = w;
    29         return;
    30     }
    31     int m = (l + r) >> 1;
    32     build(lson);
    33     build(rson);
    34     pushUp(rt);
    35 }
    36 
    37 int query(int c, int l, int r, int rt)
    38 {
    39     if (l == r) {
    40         maxn[rt] -= c;
    41         return l;
    42     }
    43     int m = (l + r) >> 1;
    44     int res = maxn[rt << 1] >= c ? query(c, lson) : query(c, rson);
    45     pushUp(rt);
    46     return res;
    47 }
    48 
    49 int main()
    50 {
    51     //freopen("debug\in.txt", "r", stdin);
    52     //freopen("CON", "w", stdout);
    53     int i, j, k;
    54     int n;
    55     while (~scanf("%d%d%d", &h, &w, &n)) {
    56         int right;
    57         if (h > n) right = n;
    58         else right = h;
    59         build(1, right, 1);
    60         int width;
    61         while (n--) {
    62             scanf("%d", &width);
    63             if (maxn[1] < width)
    64                 printf("-1
    ");
    65             else
    66                 printf("%d
    ", query(width, 1, right, 1));
    67         }
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    从数据到代码—通过代码生成机制实现强类型编程
    .NET中oledb访问access含子查询的语句的参数置换顺序
    Android开发入门学习
    Shell脚本初步学习鸟哥Linux私房菜基础学习篇
    rpm打包学习
    关于计算机工作方向的几点想法
    source insight中文注释乱码问题的解决方案
    makefilerpm编译软件,输出依赖软件包的编译顺序
    在android中资源文件夹中添加一个新的图片资源
    Linux批量替换某种类型文件中的字符串sed和grep命令使用
  • 原文地址:https://www.cnblogs.com/lc520love/p/5359253.html
Copyright © 2020-2023  润新知