HDU 2795 Billboard【点修改】
<题目链接>
题目大意:
有一块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【点修改】的更多相关文章
- HDU 2795 Billboard(宣传栏贴公告,线段树应用)
HDU 2795 Billboard(宣传栏贴公告,线段树应用) ACM 题目地址:HDU 2795 Billboard 题意: 要在h*w宣传栏上贴公告,每条公告的高度都是为1的,并且每条公告都要 ...
- HDU 2795 Billboard(线段树的另类应用)
Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- hdu 2795 Billboard(线段树+单点更新)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others ...
- HDU 2795——Billboard——————【单点更新、求最小位置】
Billboard Time Limit:8000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit St ...
- HDU 2795 Billboard 【线段树维护区间最大值&&查询变形】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2795 Billboard Time Limit: 20000/8000 MS (Java/Others) ...
- hdu 2795 Billboard 线段树单点更新
Billboard Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=279 ...
- HDU 2795 Billboard (线段树+贪心)
手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/article/details/77488127 URL: http ...
- HDU 2795 Billboard (线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告; 然后给n个1*wi的广告,要求把广告贴 ...
- ACM学习历程—HDU 2795 Billboard(线段树)
Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h ...
随机推荐
- UE4的AI学习(1)——基本概念
AI学习当中,不学习行为树基本概念就不能明白具体实例中的操作意义,但是没有经过具体实例实验,又觉得基本概念抽象难以理解.建议先泛读(1)(2)后再对具体的细节进行死磕,能较深的理解行为树的具体概念.第 ...
- day3 进入指定目录:cd
想进入指定目录使用cd cd 目录名 进入指定目录 进入系统根目录:cd / 回退命令:cd .. 或者 cd ../ 或者 cd ..// 进入当前用户的主目录:cd 或者 cd ~ 跳转指定目录: ...
- Failed to load or instantiate TagLibraryValidator class: org.apache.taglibs.standard.tlv.JstlCoreTLV
今天在使用JSP,引入<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ...
- mysql安装与卸载(非绿色版)
一.安装和卸载 Mysql安装路径: C:\Program Files\MySQL\MySQL Server 5.5\ Mysql数据文件存放的路径: C:\Documents and Setting ...
- 转载:Nginx的命令行控制(1.6)《深入理解Nginx》(陶辉)
原文:https://book.2cto.com/201304/19621.html 在Linux中,需要使用命令行来控制Nginx服务器的启动与停止.重载配置文件.回滚日志文件.平滑升级等行为.默认 ...
- spring事物深入了解
1.问题 1.以前对事物的了解只是停留在声明式事物,配置xml,或使用注解,事物的传播行为也只用过REQUIRED和SUPPORTS,可以说对事物的了解很模糊. 2.直到在开发中遇到问题.. 问题的描 ...
- 从零开始自己搭建复杂网络2(以Tensorflow为例)
从零开始自己搭建复杂网络(以DenseNet为例) DenseNet 是一种具有密集连接的卷积神经网络.在该网络中,任何两层之间都有直接的连接,也就是说,网络每一层的输入都是前面所有层输出的并集, 而 ...
- OneNET麒麟座应用开发之八:采集大气压力等环境参数
采集大气压力和温度也是核算大气标准状况下的各种数据的必须参数,为此我们必须知道压力和温度才能计算标准状况下的各种参数,于此我们需要一个既能检测压力也能检测温度的元件. 1.硬件概述 MS5837压力传 ...
- raindi python魔法函数(一)之__repr__与__str__
__repr__和__str__都是python中的特殊方法,都是用来输出实例对象的,如果没有定义这两个方法在打印的时候只会输出实例所在的内存地址 这种方式的输出没有可读性,并不能直观的体现实例.py ...
- 关系操作符 == != equals()
== 和!= //: object/test.java package object; import java.util.*; public class Test{ public static vo ...