HDOJ 2795 Billboard

来源:互联网 发布:汉文化 知乎 编辑:程序博客网 时间:2024/06/06 09:17

~~~题目链接~~~


题目大意:在一个高为h, 宽为w的面板上贴上n张海报, 每个海报的高都为1, 每张海报能尽可能的贴在高度最高的地方, 当同一个高度有多个地方可以贴海报时,贴在最左边, 现在求每个海报能贴在哪个高度。


思路:用线段树进行2分区间, 把高度看成区间。区间的高度为最小的(h, n), 注意n == 1时;


code:

#include <stdio.h>#define N 200002#define max(a,b) a>b? a:busing namespace std;struct node{    int id, w;}t[4*N];int h = 0, w = 0, n = 0, cnt = 0, flag = 0;void build(int c, int l, int r)//区间的值存当前所有叶子节点中能剩余贴的地方的最大宽度{    int m = l+(r-l)/2;    if(l == r)    {        t[c].id = cnt++;        t[c].w = w;        return ;    }    build(2*c, l, m);    build(2*c+1, m+1, r);    t[c].w = max(t[2*c].w, t[2*c+1].w);}int query(int c, int l, int r, int w){    int num = -1;    int m = l+(r-l)/2;    if(t[c].w<w) return -1;    if(l == r )    {        t[c].w -= w;        return t[c].id;    }    if(t[2*c].w>=w) num = query(2*c, l, m, w);    else if(t[2*c+1].w>=w) num = query(2*c+1, m+1, r, w);    t[c].w = max(t[2*c].w, t[2*c+1].w);    return num;}int main(){    int i = 0, min = 0, num[N];    while(scanf("%d %d %d", &h, &w, &n) != EOF)    {        min = h<n? h:n;        build(1, 1, min);        for(i = 0; i<n; i++)        {            cnt = 0;            int w = 0;            scanf("%d", &w);            flag = 0;            num[i] = query(1, 1, min, w);        }        for(i = 0; i<n; i++)        {                if(num[i] == -1) printf("%d\n", num[i]);                else                        printf("%d\n", num[i]+1);        }    }    return 0;}