A - Jumping Buildings Gym - 102302A(单调队列,找这个数右边第一个比他大的数)

Bob is developing a new game called jumping Lario. In this game the main protagonist, Lario, has to jump on top of buildings until he reaches the end of the level. The level is composed of N buildings of possibly different heights. The building where Lario starts is chosen randomly at the beginning of the game.

Bob started to write the code for his game but then realized that he didn’t know how to implement the jumps mechanics. The thing is, if Lario is currently on top of building X and the height of this building is h, then Lario should be able to reach building min(X + h, n) in one jump. Unless, of course, there’s a taller building somewhere on the path from building X to building X + h, then in this case, Lario would face smash the taller building on the path and end up landing right before it.

For example, in the image bellow, if Lario had started on the first building (of height 5), with one jump he should be able to reach building six. But on the path from building one to building six, he would end up hitting building five that has height 6. When doing so, he would land on building four (the one with height 3).

Given the heights for all the N buildings, your task is to figure out for every possible start position of Lario, how far he would be able to go with just one jump.

Input
The first line of the input contains a single integer N (1 ≤ N ≤ 105), indicating the number of buildings.

The second line of the input contains N integers h1, h2… hN (1 ≤ hi ≤ 105), indicating the height of each building.

Output
Output N integers. The i-th integer indicating the farthest building that Lario can reach with one jump if he starts on top of the i-th building.

Example
Input
6
5 2 2 3 6 2
Output
3 1 0 0 1 0

题意: 找这个数右边第一个比他大的数
思路: 单调队列一眼题,使其出队列的数就是这个最先比他大的数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 7;
int q[maxn],a[maxn],ans[maxn];

int main()
{
    int n;scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&a[i]);
    }
    
    int h = 0,l = 0;
    for(int i = 1;i <= n;i++)
    {
        while(l > h && a[q[l]] < a[i])
        {
            ans[q[l]] = i;
            l--;
        }
        q[++l] = i;
    }
    
    for(int i = 1;i <= n;i++)
    {
        if(ans[i] == 0)
            ans[i] = n + 1;
    }
    for(int i = 1;i <= n;i++)
    {
        printf("%d ",min(a[i],ans[i] - i - 1));
    }
    return 0;
}
上一篇:Unity3D开发学习⑥ 跳跃动画,LayerMask


下一篇:以Jump Game为例,逐层击破动态规划