题目链接: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;
}