<题目链接>

题目大意:

有一块h*w的矩形广告板,要往上面贴广告,然后给n个1*wi的广告,要求把广告贴上去,而且要求广告要尽量往上贴并且尽量靠左, 求第n个广告的所在的位置,不能贴则为-1。

解题分析:

先抛开本题的数据范围不谈,本题的思路就变的十分简单,无非就是每输入一个纸条的长度,判断一下该广告牌上剩余长度最大的层的剩余长度是否大于该纸条长度,若大于,则该层剩余长度要减去这个纸条的长度,若小于,则输出-1。

但很不幸,本题的数据范围十分之大,如果直接暴力查找剩余长度最大的层,毫无疑问会超时,于是这里要用到线段树。线段树作用也是快速查找剩余长度最大的层,明白了这一点,本题就可以做了。具体实现见代码(附有详细解析)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; #define L l,m,rt<<1
#define R m+1,r,rt<<1|1 //u*2+1 const int N = + ;
int h, w, n;
int a[N << ]; void build(int l, int r, int rt) //建立线段树的规则为,最后叶子的序号与层数的序号相对应,比如第一片叶子表示第一层…… 每一个节点的区间范围表示对应的层数范围
{ //若a[rt]表示的是叶子,则a[rt]的值为对应层剩余的长度
a[rt] = w; //因为开始每一层都是剩余w的长度,所以每一个节点都初始化为w //若a[rt]表示的是节点,则a[rt]的值表示该节点对应区间(层数)的剩余长度的最大值(在下面query()函数的过程中有体现)
if (l == r)
return;
int m = (l + r) >> ;
build(L);
build(R);
} int query(int x, int l, int r, int rt)
{
if (l == r)
{
a[rt] -= x; //由于题目说了在每一层,纸条是优先放在最左边(优先放最右边也一样),所以,对于这种连续的放置,就可以直接转化为数值的加减就可以,如果题目规定了纸条放置的不同规则,那么纸条的放置则可能需要模拟了
return l;
}
int m = (l + r) >> ;
int res = (a[rt << ] >= x) ? query(x, L) : query(x, R); //优先放在上层
a[rt] = max(a[rt << ], a[rt << | ]); //递归到叶子后,由于该叶子对应层的剩余长度已经改变,所以线段树对应路径上的节点的值也应该随之改变,同时可以根据这里可以看出,该线段树每个节点存储的值为该节点对应区间(对应层数)中剩余长度的最大值
return res;
} int main()
{
while (~scanf("%d%d%d", &h, &w, &n))
{
if (h>n)
h = n;
build(, h, );
while (n--)
{
int x;
scanf("%d", &x);
if (a[]<x) //a[i]存放的是第i层所能存放的最长长度,因此a[1]表示所有层中剩余长度最长的长度,因为此线段树的节点与叶子的关系为,a[rt] = max(a[rt << 1], a[rt << 1 | 1]);
printf("-1\n");
else
printf("%d\n", query(x, , h, ));
}
}
return ;
}

代码二:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std; const int maxn=+; #define ll long long
ll h,w,n;
ll tr[maxn*]; void Pushup(int rt){tr[rt]=max(tr[rt<<],tr[rt<<|]);} void buildtree(int rt,int l,int r){
if(l==r){
tr[rt]=w;
return;
}
int mid=(l+r)>>;
buildtree(rt<<,l,mid);
buildtree(rt<<|,mid+,r);
Pushup(rt);
} int Insert(int rt,ll w,int l,int r){ //将广告牌插入,顺便更新线段树
if(l==r){
tr[rt]-=w;
return l;
}
int mid=(l+r)>>;
int ans=(w<=tr[rt<<])?Insert(rt<<,w,l,mid):Insert(rt<<|,w,mid+,r);
Pushup(rt);
return ans;
} int main(){
while(scanf("%lld %lld %lld",&h,&w,&n)!=EOF){
if(h>n){ h=n;}
int height=h;
buildtree(,,height);
for(int i=;i<=n;i++){
ll a;
scanf("%lld",&a);
if(a>tr[]){
printf("-1\n");
continue;
}
printf("%d\n",Insert(,a,,height));
}
}
return ;
}

HDU 2795 Billboard【点修改】的更多相关文章

  1. HDU 2795 Billboard(宣传栏贴公告,线段树应用)

    HDU 2795 Billboard(宣传栏贴公告,线段树应用) ACM 题目地址:HDU 2795 Billboard 题意:  要在h*w宣传栏上贴公告,每条公告的高度都是为1的,并且每条公告都要 ...

  2. HDU 2795 Billboard(线段树的另类应用)

    Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  3. hdu 2795 Billboard(线段树+单点更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others ...

  4. HDU 2795——Billboard——————【单点更新、求最小位置】

    Billboard Time Limit:8000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit St ...

  5. HDU 2795 Billboard 【线段树维护区间最大值&&查询变形】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others) ...

  6. hdu 2795 Billboard 线段树单点更新

    Billboard Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=279 ...

  7. HDU 2795 Billboard (线段树+贪心)

    手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/article/details/77488127 URL: http ...

  8. HDU 2795 Billboard (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告;   然后给n个1*wi的广告,要求把广告贴 ...

  9. ACM学习历程—HDU 2795 Billboard(线段树)

    Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h ...

随机推荐

  1. saltstack系列~第二篇

    一 简介:今天咱们来继续学习saltstack 二 命名和分组 1 命名规则 1 ID构成 机房-DB类型-角色(主/从)-IP地址 2 分组构成  分为master slave两组即可 2 分组规则 ...

  2. mysql 架构~MGR监控手段

    一 简介 今天咱们来聊聊MGR的监控 二 监控 方面: 1 节点mysql进程监控                       2 节点mysql复制进程的监控                    ...

  3. 使用layer 弹出对话框 子父页面相互参数传递 父页面获取子页面参数实例

    一.先看效果: 1.点击三个点的图标弹出了子页面: 2.子页面调用父页面方法,图一调用父页面方法,图二得到父页面var变量.           3.选择之后,关闭弹框,父页面得到子页面单选框选择的v ...

  4. 2018-2019 前期任务(一):资料阅读&Python入门

    2018-2019 前期任务(一):资料阅读&Python入门 资料原文地址:Dumbcoin - An educational python implementation of a bitc ...

  5. OGG实现两台Oracle数据库的同步

    今天通过最简单的一个例子,给大家讲解下 goldengate 实现两台Oracle数据库的同步.内容如下:1.配置数据库信息.2.安装golden gate.3.配置golden gate.4.测试同 ...

  6. PLSQL_day01

    declare begin  dbms_output.put_line('Hello world') end;

  7. 【自己开发】Jquery的loading插件

    经过几周的时间的开发.我的loading插件终于上线了.这个插件功能为客户提供正在等待的信息,提供优良用户体验效果. 先看效果. 原理我内部实现我不讲,特别简单. 我说调用方式和api. 首先引用jq ...

  8. Linux 获取设备树源文件(DTS)里描述的资源【转】

    转自:http://www.linuxidc.com/Linux/2013-07/86839.htm 转自:http://blog.sina.com.cn/s/blog_636a55070101mce ...

  9. 从Linux内核中获取真随机数【转】

    转自:http://www.cnblogs.com/bigship/archive/2010/04/04/1704228.html 内核随机数产生器 Linux内核实现了一个随机数产生器,从理论上说这 ...

  10. Innodb ,MyISAM

    1. InnoDB不支持FULLTEXT类型的索引. 2. InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算 ...