题意:给你一个长方形的木板,往上面贴广告,广告的要求是如果第一行可以贴下那么就贴在第一行,而且尽可能的往左贴,最后输出这个广告贴在哪一行。给你高度h,宽度w的长方形木板和n个操作,下面有n行操作,每一行有一个数表示广告的宽度,所有广告的高度都是1.如果木板可以容纳这个广告就输出贴在哪行,如果不能就输出-1。
思路:因为之前别人介绍这道题的时候说这是道坑题,所以先百度看了一下坑的所在,这题的数据看起来很大,10的9次方,但是其实我们只要按照他的高度建树就可以了,坑就在这个地方,如果按照宽度建树,肯定会爆掉,因为他最多有n个广告,所以高度最大就是n=200000;那么我们只要按照这个来建树就简单的很多了,想到这里那么这题也就是一道水题了。只要建树的时候看一下到底是h还是n大,谁小就按照谁建树就OK了,虽然思路看过了,但是自己写的时候建树的时候逻辑没处理好,非法内存访问了几次,还是太弱了,QAQ。
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAX 220000
int value[4*MAX];//这个数组表示当前节点我还有多少空间可用
void build(int l,int r,int id,int val)
{
value[id]=val;
if(l==r)return ;
int mid=l+r>>1;
build(l,mid,id<<1,val);
build(mid+1,r,id<<1|1,val);
}
void updata(int l,int r,int id,int val)
{
if(l==r)
{
value[id]-=val;
printf("%d\n",l);
return ;
}
int mid=l+r>>1;
if(val<=value[id<<1])updata(l,mid,id<<1,val);
else updata(mid+1,r,id<<1|1,val);
value[id]=max(value[id<<1],value[id<<1|1]);//更新当前节点
}
int main()
{
int h,w,n,t;
while(scanf("%d %d %d",&h,&w,&n)!=EOF)
{
if(h>MAX)
h=MAX;
build(1,h,1,w);//建树
while(n--)
{
scanf("%d",&t);
if(t>value[1])
{
printf("-1\n");
continue;
}
updata(1,h,1,t);
}
}
return 0;
}