3 5 5 2 4 3 3 3
1 2 1 3 -1
题意:
有一个 h * w 的矩形广告板,现在要在上面贴海报;
每个海报的大小规格是 1 * w , 要求每个海报要尽量往上并且尽量靠左贴;
求第 n 个海报的所在的位置;
如果不能再贴海报则输出 -1;
PS:
我们可以运用线段树来求得区间的最大值;
我们可以将位置也就是 h 来建树,树中节点存的是当前区间还拥有的最大空间;
如果左子树的最大值大于 x ,就查询左子树,反之就查询右子树;
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
const int maxn = 200017;
int a[maxn << 2];
int h, w, n;
void pushup(int rt) //把当前结点的信息更新到父结点
{
a[rt] = max(a[rt<<1], a[rt<<1|1]);
//a[rt] = a[rt<<1] + a[rt<<1|1];
}
void build(int l, int r, int rt)
{
if(l == r)
{
a[rt] = w;
return ;
}
int mid = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int query(int x, int l, int r, int rt)
{
if(l == r)
{
a[rt]-=x;
return l;
}
int mid = (l+r)>>1;
int ret = 0;
if(x <= a[rt<<1])//x小于左子树的最大值
ret = query(x, lson);
else
ret = query(x, rson);
pushup(rt);
return ret;
}
int main()
{
while(~scanf("%d%d%d",&h,&w,&n))
{
if(h > n)
{
h = n;
}
build(1, h, 1);
int x;
for(int i = 1; i <= n; i++)
{
scanf("%d",&x);
if(a[1] < x)//最大值都小于x
{
printf("-1\n");
continue;
}
int ans = query(x, 1, h, 1);
printf("%d\n",ans);
}
}
return 0;
}
/*
4 6 6
2
4
3
3
3
5
*/
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u012860063/article/details/47261163