题意:给一个h*w的公告牌,h是高度,w是宽度,一个单位高度1为一行,然后会有一些公告贴上去,公告是1*wi大小的长纸条,优先贴在最上面并且最左边的位置,如果没有空间贴得下,就输出-1,可以的话,就输出所贴的位置(第几行)
思路:每次贴一张,去找一个空间>=w的最左上边的位置,所以优先进入左孩子,每次都要把孩子所剩空间的最大值更新至父节点
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <stack>
#define lson l,mid,num<<1
#define rson mid+1,r,num<<1|1
using namespace std;
const int M=200005;
int Max[M<<2];
int h,w,n,a;
void Pushup(int num)
{
Max[num]=max(Max[num<<1],Max[num<<1|1]);
}
void build(int l,int r,int num)
{
Max[num]=w;
if(l==r)return;
int mid=(l+r)>>1;
build(lson);
build(rson);
}
int query(int x,int l,int r,int num)
{
if(l==r)
{
Max[num]-=x;//求所剩的最大值
return l;
}
int mid=(l+r)>>1;
int ret=(Max[num<<1]>=x)?query(x,lson):query(x,rson);
Pushup(num);//更新至父节点
return ret;
}
int main()
{
while(scanf("%d%d%d",&h,&w,&n)!=EOF)
{
if(h>n)h=n;
build(1,h,1);
for(int i=1;i<=n;i++)
{
scanf("%d",&a);
if(Max[1]<a)printf("-1\n");//在父节点判断就好
else
printf("%d\n",query(a,1,h,1));
}
}
return 0;
}