zoukankan      html  css  js  c++  java
  • CodeForces

    CF6E Exposition

    题目大意:

    给一个(n)个元素的序列,从中挑出最长的子串,要求子串中元素差的最大值不超过(k)。问有几个最长子串,子串长度,以及这几个子串的起始、终止位置。

    思路:

    很容易想到尺取法。

    我们使用(multiset)来完成对维护尺取的区间,因为(multiset)具有有序性和可充分性,而且在默认的情况下,该容器内的元素是使(<)运算符比较大小,也就是容器内部按升序排列。所以我们可以通过(crbegin())(cbegin())分别取出容器内的最大值和最小值进行模拟。

    值得一提的是,在模拟单调队列的弹出操作时,我们使用

    [MuiltisetName.erase(MuiltisetName.find(value)) ]

    来删除指定值。因为如果直接删除指定值的话,(erase)函数会将所有与指定值相同的元素删去,就不符合题意了。

    Code:
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 100010;
    const int INF = 0x3f3f3f3f;
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
        while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    
    int main() {
        int n = read(), k = read();
        vector<pair<int, int> > p;
        multiset<int> s;
        vector<int> h(N);
        int l = 0, max_len = 0;
        for (int r = 0; r < n; r++) {
            h[r] = read();
            s.insert(h[r]);
            while (*s.crbegin() - *s.cbegin() > k)
                s.erase(s.find(h[l++]));
            if (r - l + 1 > max_len) {
                p.clear(); //要记录最长序列长度的位置
                max_len = r - l + 1;
                p.push_back(make_pair(l + 1, r + 1));
            } else if (r - l + 1 == max_len) {
                p.push_back(make_pair(l + 1, r + 1));
            }
        }
        printf("%d %d
    ", max_len, p.size());
        for (auto i : p) {
            printf("%d %d
    ", i.first, i.second);
        }
        return 0;
    }
    
  • 相关阅读:
    C++ fstream 用法
    Servlet详解(转)
    JSP&Servlet(转)
    我们工作是为了什么!
    常见C C++问题(转)
    一份诚恳的互联网找工作总结和感想(附:怎样花两年时间去面试一个人)
    第一篇
    洛谷p1064 金明的预算方法
    onload、DOMContentLoaded与性能问题
    jsbin本地部署
  • 原文地址:https://www.cnblogs.com/Nepenthe8/p/13687137.html
Copyright © 2011-2022 走看看