HDU 2795 Billboard(线段树)

来源:互联网 发布:考研对未来的意义 知乎 编辑:程序博客网 时间:2024/04/29 12:03

题目链接:Click here

题意:有一块h*w的墙,有n个宣传单 每个的大小为 1*wi 每次贴都从最左最上能贴的位置开始。求每一宣传单被贴在哪一行。

思路:将墙从1~h划分成h个区间,建立线段树,每个区间的信息为所能贴的最大宽度len[i],每次查找,找到后输出,更新区间信息。

#include <iostream>#include <cstring>#include <cstdio>#include <queue>using namespace std;int len[800005], w;void build(int left, int right, int f){    int mid;    mid = (left + right) / 2;    if(left == right)        len[f] = w;    else    {        build(left, mid, f * 2);        build(mid + 1, right, f * 2 + 1);        len[f] = w;    }}int que(int qw,int left, int right, int f){    int place, mid;    mid = (left + right) / 2;    if(left == right)    {        len[f] -= qw;        return left;    }    if(len[f * 2] >= qw)        place = que(qw, left, mid, f * 2);    else        place = que(qw, mid + 1, right, f * 2 + 1);    if(len[f*2] > len[f*2+1])        len[f] = len[f*2];    else        len[f] = len[f*2+1];    return place;}int main(){    int s, h, n;    while(scanf("%d%d%d", &h, &w, &n) != EOF)    {        if(h > n)            h = n;        build(1, h, 1);        while(n--)        {            scanf("%d", &s);            if(s > len[1])                printf("-1\n");            else                printf("%d\n", que(s,1,h,1));        }    }    return 0;}
0 0
原创粉丝点击