向右看齐 ( 洛谷P2947)

文章提供了两种方法,使用STL的stack和手写栈,来解决一个编程题目。代码实现了一个单调栈的算法,用于确定数组中每个元素的仰望对象,即找到比其更高的元素。在遍历过程中,栈中始终保持比当前元素高的元素,从而找到每个元素的仰望对象。
摘要由CSDN通过智能技术生成

题目链接:https://www.luogu.com.cn/problem/P2947

       

        这里可以运用单调栈,STL 或者手写

        ①以下是STL

#include <iostream>
#include <stack>

using namespace std;

int h[ 100001 ], ans[ 100001 ];

int main ( )
{
    int n, i;
    scanf ( "%d", &n );

    for ( i = 1; i <= n; ++ i )
    {
        scanf ( "%d", &h[ i ] );
    }

    stack<int> st;

    for ( i = n; i >= 1; -- i )
    {
        while ( !st.empty( ) && h[ st.top( ) ] <= h[ i ] )
        {
            st.pop( );      //栈顶奶牛没有 i 高,弹出它,直到栈顶奶牛更高为止
        }

        if ( st.empty ( ) ) //栈空,没有仰望对象
        {
            ans[ i ] = 0;
        }
        else
        {
            ans[ i ] = st.top( );   //栈顶奶牛更高,是仰望对象
        }

        st.push ( i );  //进栈
    }

    for ( i = 1; i <= n; ++ i )
    {
        printf ( "%d\n", ans[ i ] );
    }

    return 0;
}

        ②以下是手写栈

#include <iostream>

using namespace std;

const int N = 100100;

struct mystack
{
    int a[ N ]; //存放栈元素,int型
    int t = 0;  //栈顶位置

    void push ( int x ) //送入栈
    {
        a[ ++ t ] = x;
    }

    int top ( ) //返回栈顶元素
    {
        return a[ t ];
    }

    void pop ( )    //弹出栈顶
    {
        -- t;
    }

    int empty ( )   //返回 1 表示空
    {
        return t == 0 ? 1 : 0;
    }
}st;

int h[ N ], ans[ N ];

int main ( )
{
    int n, i;
    scanf ( "%d", &n );

    for ( i = 1; i <= n; ++ i )
    {
        scanf ( "%d", &h[ i ] );
    }

    for ( i = n; i >= 1; -- i )
    {
        while ( !st.empty ( ) && h[ st.top() ] <= h[ i ] )
        {
            st.pop( );  //栈顶元素没有当前奶牛高,弹出它
        }

        if ( st.empty ( ) )
        {
            ans[ i ] = 0;   //栈空,没有奶牛比当前奶牛高
        }
        else
        {
            ans[ i ] = st.top ( );  //栈顶元素比当前奶牛高,是仰望对象
        }

        st.push ( i );
    }

    for ( i = 1; i <= n; ++ i )
    {
        printf ( "%d\n", ans[ i ] );
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值