看了一会题,终于把题意弄明白了,一块板子,上面贴一些海报,但是这些海报贴起来是有规律的。
板子的大小是 h *w, 海报的大小是 1*wi.
我每次都是选择最高的最左的地方贴,如果没有位置给我贴,那就输出-1。。(题意就是这个样子)
那么刚开始看这题,感觉用模拟,肯定会很墨迹,而且数据很大,可能得挂。。
后来参考了别人的代码(这几天线段树的练习好像都是参考代码啊啊~~~~):
是这个样一个思路: 线段树的叶子节点存板子的宽度也就是 W, 而线段树每个节点的区间就代表1-h。。
所以我总结出了一个玩意:(如果一个
问题要用线段树来解决,那么你首先得知道,线段树的叶子表示啥,线段树节点的区间表示啥,然后找到叶子与区间的某种关系,顺着这种关系来解决问题,基本上是通过递归)
附上代码
#include <iostream>
#define N 800000
using namespace std;
struct node
{
int maxn,l,r;
}st[N];
int h,w,n;
void build(int v,int l,int r)
{
st[v].l=l;
st[v].r=r;
st[v].maxn=w;
if(l==r)return;
int mid=(st[v].l+st[v].r)/2;
build(2*v,l,mid);
build(2*v+1,mid+1,r);
}
int find(int v,int d)
{
if(st[v].maxn<d)return -1;
if(st[v].l==st[v].r)
{
st[v].maxn=st[v].maxn-d;
return st[v].l;
}
int t=find(2*v,d);
if(t==-1)t=find(2*v+1,d);
if(t)
st[v].maxn=max(st[v*2].maxn,st[v*2+1].maxn);
return t;
}
int main()
{
while(scanf("%d%d%d",&h,&w,&n)!=EOF)
{
if(h>n)h=n+100;
build(1,1,h);
int temp;
for(int i=0;i<n;i++)
{
scanf("%d",&temp);
int s=find(1,temp);
printf("%d\n",s);
}
}
return 0;
}