• HDU2795 Billboard 题解


    HDU2795 Billboard

    线段树例题解析合集

    题意:有一个h行w列的矩形,在里面横放m条大小为1*l[i]的小长方形,不能重叠,如果能放得下,输出能放下的最小行数,放不下输出-1

    由于只有m个长方形,最多只需要m行(h范围很大),把h对m取min

    然后维护每行剩下的值的区间最大值,查询时若左子树代表区间内的最大值>需要的长度,向左子树递归,否则考虑右子树,若长度都不够,答案为-1

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10;
    inline void read (int &x) {
        char ch = getchar(); x = 0;
        while (!isdigit(ch)) ch = getchar();
        while (isdigit(ch))  x = x * 10 + ch - 48, ch = getchar();
    }
    inline int print (int x) {
        if (x < 0) putchar ('-'), x = -x;
        if (x > 9) print (x / 10);
        putchar (x % 10 + 48);
    }
    int h, w, n, val, c[N << 2];
    #define ls p << 1
    #define rs p << 1 | 1
    inline int Max (int a, int b) {return a > b ? a : b;}
    int query (int p, int l, int r, int val) {
        if (l == r) {
            if (c[p] >= val) {c[p] -= val; return l;}
            else return -1;
        }
        int mid (l + r >> 1), ans (-1);
        if (c[ls] >= val) ans = query (ls, l, mid, val);
        else if (c[rs] >= val) ans = query (rs, mid + 1, r, val);
        c[p] = Max (c[ls], c[rs]);
        return ans;
    }
    int main() {
        while (~scanf ("%d %d %d", &h, &w, &n)) {
            if (n < h) h = n;
            for (int i = 1; i <= (h << 2); ++i) c[i] = w;
            for (int i = 1; i <= n; ++i) {
                read (val);
                if (val > w) puts ("-1");
                else print (query (1, 1, h, val)), puts ("");
            }
        }
        return 0;
    }
    
  • 相关阅读:
    linux命令(3)top
    linux命令(2)vmstat
    学习okhttp wiki--Connections.
    你可以更幸福(转载)
    Android中多表的SQLite数据库(译)
    怎样写有效的设计文档(译)
    Material Design说明
    Android原生Calendar代码阅读(一)
    Android Studio tips and tricks 翻译学习
    Material Calendar View 学习记录(二)
  • 原文地址:https://www.cnblogs.com/whx666/p/12041534.html
Copyright © 2020-2023  润新知