poj3250 Bad Hair Day(单调栈)

来源:互联网 发布:淘宝怎么搜阿普唑仑 编辑:程序博客网 时间:2024/05/16 07:08

博主表示菜鸟一个,刚刚开通博客,记录下自己学习变成的过程,同时希望能和大家交流经验,能帮助到其他人;

这道题题意为

输入牛的头数(0<=N<80000),并输入每头牛的高度,按照输入的顺序吧所有的牛排成一行,一直每头牛只能看见自己右边比自己矮的牛直到遇到比自己高的牛为止;要求是输出所有牛能看见自己右边的牛的头数的总和;

这道题给人的第一印象是使用双重循环挨个遍历,但由于题目给出的数据太大,双重循环的时间复杂性是o(n2),这样下来就超时了;

所以换位思考使用栈来实现,利用栈先进后出的特点,计算出每头牛能被看见的次数,并求和输出,这样的时间复杂性是o(n);

思路如下:

从左边第1头牛向右开始遍历,将第一个压入栈,由于能看见第N+1头牛必能看见第N头牛,所以遍历第N+1牛时可以就直接用遍历完第N头牛的栈;

如果当前遍历牛的高度小于栈顶的高度,说明当前牛能被栈顶所属高度及其占顶一下的牛看见,如果当前遍历的牛的高度高于栈顶,说明栈顶所在牛不能看见当前的牛,

此时弹栈,直至栈顶大于当前牛的高度;此时栈的长度即为能看见当前牛的次数,用一重循环遍历,并求和既能得出结果;需注意的是由于数据较大,sum需用long long型的否者会出现错误。(程序有部分是参考的,加上自己理解和改进写出,希望大家遇到不太会的程序千万不要灰心丧气,要相信自己)

#include<iostream>
#include<stack>
#define N 80001
using namespace std;
int n;

int main()
{
    stack<int> hi;
    int cow[N],i;
    long long sum=0;
     cin>>n;
     for(i=1;i<=n;i++)
     cin>>cow[i];
     for(i=1;i<=n;i++)
     {
         while((hi.empty()!=true)&&(cow[i]>=hi.top()))
          hi.pop();
          sum+=hi.size();
          hi.push(cow[i]);
     }
    cout<<sum<<endl;
    return 0;
}

 

0 0
原创粉丝点击