zoukankan      html  css  js  c++  java
  • P1823 [COI2007] Patrik 音乐会的等待 单调栈 洛谷luogu

    题目描述

    N个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么他们是可以互相看得见的。

    写一个程序计算出有多少对人可以互相看见。

    输入输出格式

    输入格式:

    输入的第一行包含一个整数N (1 ≤ N ≤ 500 000), 表示队伍中共有N个人。

    接下来的N行中,每行包含一个整数,表示人的高度,以毫微米(等于10的-9次方米)为单位,每个人的调度都小于2^31毫微米。这些高度分别表示队伍中人的身高。

    输出格式:

    输出仅有一行,包含一个数S,表示队伍中共有S对人可以互相看见。

    输入输出样例

    输入样例#1: 复制
    7 
    2 
    4 
    1 
    2 
    2 
    5 
    1
    输出样例#1: 复制
    10

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include<bits/stdc++.h>
    using namespace std;
    
    stack<long long>stk;//存元素 
    stack<long long>num;//存相同元素数量 (两个栈同步)
    stk 9 6 (栈顶)
    num 3 2 (栈顶)
    备注 (栈中有·3个9) (2个6)  
    
    int n;
    long long ans,tmp;  //ans 累加器 
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&tmp);
            while(!stk.empty() && stk.top() < tmp)  //如果栈不为空 且栈顶元素比tmp小 那么看得到栈顶元素 
            {
                stk.pop();
                ans += num.top();
                num.pop();
            }
            if(stk.empty())//若元素栈是空的 直接塞进去就好了 
            {
                stk.push(tmp);
                num.push(1);
            }else//栈不是空的 
            {
                if(tmp != stk.top())//栈顶元素与读到的元素不相同的情况 
                {
                    ans+=1;//两人紧挨 肯定能看得到对方 故 累加器加1 
                    stk.push(tmp);
                    num.push(1);
                }else//栈顶元素与读到的元素相同的时候
                if(stk.size() == 1) //仅有一个元素 
                {
                    ans+=num.top();
                    int u = num.top();
                    num.pop();
                    num.push(u+1);
                }
                else//栈顶元素与读到的元素相同的时候 且 有多个元素 
                {
                    ans += num.top();
                    int u = num.top();
                    num.pop();
                    ans += 1;
                    num.push(u+1);
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
     } 

    分情况讨论

    (1).栈为空:直接把新元素压入就好

    (2).栈不为空1.栈顶元素<tmp

                    栈顶元素都看得到

                    累加器+=栈顶元素个数

                    弹出栈顶元素

            2.栈顶元素=tmp

                    <1> 栈中仅有一个元素

                              都看得到

                              stk不变;   tmp的值(唯一的元素的值)+1

                    <2>栈中仍有多个元素

                              都看得到

                              stk不变;   tmp的值(唯一的元素的值)+1

                              同时也相当于与相邻元素紧挨 ans+1

            3.栈顶元素>tmp

                    由于紧挨着 ans+1

    备注:

      1.从上到下依次特判 调整顺序不可以

      2.开long long

      3.注意ans是+1还是+num.tpo();   

                              

      

     

     

  • 相关阅读:
    动手篇:简易的首页登陆界面
    情感交流篇:HTML页面如何与后端联系
    MD5加密处理
    处女篇:自用C#后端SqlHelper.cs类
    动手篇:简单的注册界面与防SQL注入(续)
    十二省联考2019 字符串问题
    PKUWC2020游记
    uoj435 Simple Tree
    CF1303G Sum of Prefix Sums
    AGC069F Flags
  • 原文地址:https://www.cnblogs.com/darlingroot/p/10306645.html
Copyright © 2011-2022 走看看