hdoj 2795 Billboard

Billboard

题目意思很简单,给一个面积为h*w的板子,每次选择一个最上且最左的区域贴上一张纸1*wi,求每次贴的行。每次找出行中保留面积能够满足纸的面积的即可。如果直接用数组模拟的话,肯定会超时。这个题目可以用线段树做。看题的时候,发现h比较大,开数组肯定会超内存。分析一下,发现有n次插入,我们可以假设每次都只能在新的一行中插入,在极限数据下,也只需要4*200000的空间,这样肯定不会超内存。结构体中保存一个最大值,也是每个区间的剩余面积。在每次查询的时候,由于要更新每行的数据,所以要在回调更新最大值。代码如下:

/*
ID : csuchenan
PROG: Billbord hdoj 1795
LANG: C++
*/

#include<stdio.h>

#define MAXN 300010
 
struct Node{
	int l ;
	int r ;
	int nmax ;
}node[MAXN * 4] ;

int h ;
int w ;
int n ;

bool init() ;
void work() ;

void build(int l , int r , int c) ;
int  query(int val , int c) ;

int main(int argc , char *argv[]){
	
	while(init()){
		work() ;
	}
	
	return 0 ;
}

bool init(){

	if(scanf("%d %d %d" , &h , &w , &n)!=3){
		return 0 ;
	}
	
	if(h > n)
		h = n ;
		
	build(1 , h , 1) ;
		
	return 1 ;
}

void work(){
	
	int val ;
	int res ;
	
	while(n--){
		scanf("%d" , &val) ;
		res = query(val , 1) ;
		
		printf("%d\n" , res) ;
	}
}

void build(int l , int r , int c){

	node[c].l = l ;
	node[c].r = r ;
	node[c].nmax = w ;
	
	if(l == r)
		return ;
	
	int mid = (l+r)>>1 ;
	
	build(l , mid , c<<1) ;
	build(mid + 1 , r , c<<1|1) ;
	
	return ;
}

int query(int val , int c){
	
	if(node[c].nmax < val){
		return -1 ;
	}
	if(node[c].l==node[c].r){
		node[c].nmax -= val ;
		return node[c].l ;
	}
	int result ;
	
	if(node[c<<1].nmax >= val)
		result = query(val , c<<1) ;
	else
		result = query(val , c<<1|1) ;
	
	node[c].nmax = (node[c<<1].nmax) > (node[c<<1|1].nmax) ? (node[c<<1].nmax) : (node[c<<1|1].nmax) ;
	
	return result ;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值