HDU2795 贴广告
来源:互联网 发布:网络发展新技术 编辑:程序博客网 时间:2024/05/17 07:44
HDU2795 Billboard
题意:有一块h*w的广告牌,往上面贴n个1*wi的广告(不可覆盖),尽量贴最上面,满足最上面时尽量贴最左边,如果哪个广告贴不下不能就输出-1,贴的下就输出它在哪一行
思路:如果以行数为区间,建立线段树,广告最多有n=200000条,即使每个广告一行也就需要h=200000行就足够了;树的叶子节点表示广告牌的高度,而父节点存储子节点的最大剩余值;所以每次找到最大值的位置(位于叶子节点)然后减去wi
#include<cstdio>#include<algorithm>using namespace std;struct node{ int left,right; int len;}tree[200001*4];//广告即使每个占一行,最多也就200000行,所以h最大200000就够了int w,v;//广告牌的宽及广告的宽void Build(int l,int r,int cur){ tree[cur].left=l; tree[cur].right=r; tree[cur].len=w;//叶子节点放入牌子的宽度,其他节点放入左右儿子节点的最 //大值,刚开始叶子都一样所以最大值也就是广告牌的宽度 if(l==r)return ; int mid=(l+r)/2; Build(l,mid,cur*2); Build(mid+1,r,cur*2+1);}int Query(int cur){//查询和更新结合在一起 if(tree[cur].left==tree[cur].right){ tree[cur].len-=v;//贴成功 return tree[cur].left;//返回所在的行 } int ret; if(tree[cur*2].len>=v)ret=Query(cur*2);//一旦左儿子的len>=v则往左儿子找 else ret=Query(cur*2+1);//左儿子不行才找右儿子,这样保证了topmost tree[cur].len=max(tree[cur*2].len,tree[cur*2+1].len);//先更新父节点的len值 return ret;//后返回到上一层}int main(){ int h,n;//广告牌的高及广告个数 while(scanf("%d%d%d",&h,&w,&n)!=EOF){ if(h>n)h=n;//广告即使每个占一行,最多也就n行,所以当h>n时取n即可 Build(1,h,1); while(n--){ scanf("%d",&v);//广告的宽 if(tree[1].len<v)printf("-1\n");//根节点存的是所有叶子节点存的最大值 else printf("%d\n",Query(1)); } } return 0;}
0 0
- HDU2795 贴广告
- hdu2795 线段树 贴广告
- hdu2795
- hdu2795
- hdu2795
- hdu2795
- HDU2795
- hdu2795
- hdu2795
- hdu2795
- hdu2795
- HDU2795
- HDU2795
- HDU2795
- hdu2795
- HDU2795
- 线段树-hdu2795 Billboard(贴海报)
- 单点更新区间求和贴海报问题 hdu2795 billbord
- HDU1394 求逆序数
- 利用辗转相除法计算最大公约数与最小公倍数
- Xcode 7.0正式版发布了
- [C#/ASP.NET]List<>中Sort()、Find()、FindAll()、Exist()的使用方法
- python定时任务调度库_apscheduler的使用(1)
- HDU2795 贴广告
- System进程的启动流程第二部分
- 字符串相似度算法 递归与动态规划求解分析
- POJ2828 插队
- 安卓启动流程
- 最长公共子序列求解:递归与动态规划方法
- YUV4:2:2 UYVY图像旋转
- 【移动设备显示尺寸】
- POJ3264 区间最大最小值