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 ...
随机推荐
- sqlalchemy-查询
User这个类创建的表 User1这个类创建的表 基本查询结果 # 1 查看sql原生语句 rs =session.query(User).filter(User.username=='budon ...
- python安装模块方法汇总
方法一: 原文地址: http://blog.csdn.net/cighao/article/details/47860041 在 windows 系统下,只需要输入命令 pip install re ...
- VS Code中Matlab插件安装设置
Install the extension in VS Code Open the command palette using Ctrl+Shift+P Type ext install Matlab ...
- Tensorflow datasets.shuffle repeat batch方法
机器学习中数据读取是很重要的一个环节,TensorFlow也提供了很多实用的方法,为了避免以后时间久了又忘记,所以写下笔记以备日后查看. 最普通的正常情况 首先我们看看最普通的情况: # 创建0-10 ...
- VIM for C++ 一键安装配置
执行: wget https://raw.github.com/ma6174/vim/master/setup.sh -O ma6174_vim_setup.sh && bash ma ...
- ReLu、LeakyRelu、PReLu(转载)
转载链接:http://blog.csdn.net/cham_3/article/details/56049205
- 005_awk案例实战
一.工作经验总结. (1)日志案例: 10.100.194.39 10.100.194.39 1019-03-16T11:01:04+08:00 www.uuwatch.com^^3FF91DE01B ...
- 基于MFC的ActiveX控件开发教程------------浏览器插件之ActiveX开发
浏览器插件之ActiveX开发(一) 一般的Web应用对于浏览器插件能不使用的建议尽量不使用,因为其涉及到安全问题以及影响用户安装(或自动下载注册安装)体验问题.在有特殊需求(如涉及数据安全的金融业务 ...
- Java集合框架入门介绍(一)
Java工具包(java.util)提供了强大的数据结构,主要有以下几种接口或类 枚举Enumeration 接口 从数据集合中取回一系列连续值的方法 位集合 BitSet 可以单独清楚或设置的位和标 ...
- UVA101 【The Blocks Problem】
一个大模拟!!! 总的来说就是碰到move就要把a上面的全部放回原处. 如果碰到onto就要把b上面的全部放到原处. 因为move是只移动a一个,所以a上面的要归位,而pile是移一堆,所以不用. o ...