您的位置:首页 > 大数据 > 人工智能

Codeforces 272C Dima and Staircase

2015-11-21 21:04 323 查看
题目描述

迪玛得到了一个 n 级的楼梯。第一阶高 $a_1$,第二阶高 $a_2$,最后一层台阶高 $a_n (1 \le a_1 \le a_2 \le ... \le a_n)$。

迪玛想玩这些楼梯,所以他从上面忘楼梯上丢矩形盒子。第 i 个盒子宽 $w_i$,高 $h_i$。迪玛把第 i 个盒子竖直的丢到前 $w_i$ 个台阶,也就是说,这个盒子盖住了标号 $1,2,...,w_i$ 的台阶。每个盒子一直向下落,直到下面这两个事件任一发生:

- 盒子的底部碰到了楼梯的顶部

- 盒子的底部碰到了之前落下的盒子的顶部

我们只考虑与楼梯和盒子的水平边接触,与角的接触是不考虑的。确切的说,宽 $w_i$ 的盒子不会与标号 $w_i + 1$ 的楼梯接触。

给你楼梯的描述和迪玛丢盒子的序列,判断每个盒子的底部落到多高的地方。认为一个盒子在前面一个盒子落下后才开始掉落。

输入

第一行包含一个整数 $n(1\le n \le 10^5)$ -- 楼梯上台阶的数目。第二行包含一个不递减的序列,包含 n 个整数 $a_1, a_2, ..., a_n(1\le a_i \le 10^9)$。

下一行包含一个整数 $m(1\le m \le 10^5)$ -- 盒子的数量。接下来有 m 行,每行是一对整数 $w_i(1 \le w_i \le n), h_i(1 \le h_i \le 10^9)$ -- 第 i 个丢出的盒子的大小。

行中的数字都是以空格分开的。

输出

输出 m 行 -- 每个盒子落定之后底部的高度。按照输入给出盒子的的顺序打印答案。

请不要使用 %lld 占位符来读写 C++ 中的 64 位整数。最好使用 cin,cout 流或者 %I64d 占位符。

思路

不假思索的话,容易认为这个问题是对每个盒子的宽范围内最大值进行查询,然后区间更新数据的值。当然这也是可以解决问题的。不过如果注意到问题的特殊性,或者直接按照题目描述的方向去思考,就可以直接得到结果:每次落定的位置,是某台阶或者某盒子。那么如果是台阶的话,到底是哪个台阶呢?自然就是最后的台阶 $a[w_i]$;如果是某盒子,到底是哪个盒子呢?当然就是最后面的一个盒子。那么怎么判断到底是落定到盒子上还是台阶上呢?只要取两者最大值就可以了。

代码

#include <stdio.h>
#include <algorithm>

const int MAXN = 100000 + 5;
long long a[MAXN];

int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", a + i);
int m;
scanf("%d", &m);
long long hit = 0;
for (; m--; ) {
int w, h;
scanf("%d %d", &w, &h);
long long res = std::max(a[w], hit);
printf("%I64d\n", res);
hit = res + h;
}
return 0;
}


链接

http://codeforces.com/problemset/problem/272/C
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: