<题目链接>

题目大意:

有一块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. mysql 语句 GROUP_CONCAT

    select * from blog_log;+----+---------------------+-------+--------+| id | time | level | info |+--- ...

  2. Python提示AttributeError 或者DeprecationWarning: This module was deprecated解决方法

    Python提示AttributeError 或者DeprecationWarning: This module was deprecated解决方法 在使用Python的sklearn库时,发现sk ...

  3. Android BroadcastReceiver 面试解析

  4. Freemarker取list集合中数据(将模板填充数据后写到客户端HTML)

    1.模板写法: <html> <head> <title>freemarker测试</title> </head> <body> ...

  5. Python 的 six模块简介

    Python 的 six模块简介 six : Six is a Python 2 and 3 compatibility library Six没有托管在Github上,而是托管在了Bitbucket ...

  6. BFGS算法(转载)

    转载链接:http://blog.csdn.net/itplus/article/details/21897443 这里,式(2.38)暂时不知如何证出来,有哪位知道麻烦给个思路.

  7. 利用capability特征加强Linux系统安全【转】

    转自:https://blog.csdn.net/fivedragon/article/details/676849 1.简介 UNIX是一种安全操作系统,它给普通用户尽可能低的权限,而把全部的系统权 ...

  8. kafka系列四、kafka架构原理、高可靠性存储分析及配置优化

    一.概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Cl ...

  9. openstack swift节点安装手册3-最后的安装配置及验证

    以下步骤都在controller节点上执行 1.远程获取/etc/swift/swift.conf文件: curl -o /etc/swift/swift.conf https://git.opens ...

  10. 【转】每天一个linux命令(1):ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写,缺省下ls用来打印出当前目录的清单.如果ls指定其他目录,那么就会显示指定目录里的文件及文件夹清单. 通过ls命令不仅可以查看linux ...