zoukankan      html  css  js  c++  java
  • Fata7y Ya Warda! SPOJ

    题意:1e5个数围成一个环。现在要输出每个数左右第一个大于它的数的下标。若没有,则输出-1.

    题解:单调栈板题。只是要把数据压入栈压两遍来模仿环。

         具体分析:考虑一个递减的数列。要找左边最大的数,我们从左到右对于每一个数,只要往回枚举一步就能找到,时间复杂度为O(n);

            考虑一个递增的数列。同样用暴力枚举,每次都要找到头(尾),复杂度为O(n*n); 如何优化?

            我们发现在递增数列的例子中如果a[N]一直遍历到头才停止,那么只要a[N+1]>a[N],就可以直接跳过之前的n-1次遍历。

            那如何记录“一直遍历到某点才停止”呢?

            一种方法是写一个数组,记录可以走到最远的地方有点记忆递归的意思。

            另一种就是把遍历过的数全删光,这就是单调栈的思想。

            

    #define _CRT_SECURE_NO_WARNINGS
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<stack>
    #include<ctime>
    #include<list>
    #include<set>
    #include<map>
    #include<queue>
    #include<vector>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    #define INF 0x3f3f3f3f
    #define N 1111
    #define eps 1e-6
    #define pi acos(-1.0)
    #define e exp(1.0)
    //std::ios::sync_with_stdio(false);
    using namespace std;
    
    const int maxn = 1e5 + 5;
    const int mod = 1e9 + 7;
    typedef long long ll;
    typedef unsigned long long ull;
    
    stack<int>s;
    deque<int>l, r;
    int h[maxn];
    #define ONLINE_JUDGE
    int main() {
    
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        long _begin_time = clock();
    #endif
        int t; cin >> t; while (t--) {
            int n;
            while (!s.empty())s.pop();
            l.clear(), r.clear();
    
            cin >> n;
            int mx = 0, mxi = 0;
            for (int i = 1; i <= n; i++) {
                scanf("%d", &h[i]); while (!s.empty() && h[s.top()] <= h[i])s.pop(); s.push(i);//存 个下降子序列  末位是最高的那个
            }
            for (int i = 1; i <= n; i++) {
                while (!s.empty() && h[s.top()] <= h[i])s.pop();
                if (!s.empty())l.push_back(s.top());
                else l.push_back(-1);
                s.push(i);
            }
            while (!s.empty())s.pop();
            for (int i = n; i > 0; i--) {
                while (!s.empty() && h[s.top()] <= h[i])s.pop(); s.push(i);
            }
            for (int i = n; i > 0; i--) {
                while (!s.empty() && h[s.top()] <= h[i])s.pop();
                if (!s.empty())r.push_front(s.top());
                else r.push_front(-1);
                s.push(i);
            }
            int sz = l.size();
            for (int i = 0; i < sz; i++) {
                printf("%d %d
    ", l[i], r[i]);
            }
        }
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        printf("time = %ld ms.", _end_time - _begin_time);
    #endif
    return 0;
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    atitit。企业的价值观 员工第一 vs 客户第一.docx
    Atitit 实现java的linq 以及与stream api的比较
    Atitit dsl exer v3 qb3 新特性
    Atititi tesseract使用总结
    Atitit 修改密码的功能流程设计 attilax总结
    atitit.TokenService v3 qb1  token服务模块的设计 新特性.docx
  • 原文地址:https://www.cnblogs.com/SuuT/p/8869176.html
Copyright © 2011-2022 走看看