牛客编程巅峰赛S2第2场

比赛地址:
青铜&白银&黄金
钻石&王者


A:热心的牛牛

  先从 k k k块糖果中拿出 n n n块糖果平均分给 n n n个朋友,剩下的糖果再和牛牛一起平分,答案: k − n n + 1 \frac {k-n}{n+1} n+1kn.

B:牛牛切木棒

  三个木棒的构不成三角形的边界情况就是 a + b = c a+b=c a+b=c,那么对于总的木棒长度固定,只要满足斐波那契数列即可。

C:Tree II

  这个题就是考察层次遍历的时候结点编号的关系,我们可以令整棵树的根节点的编号是0,然后对于任意一颗子树的根节点,都应该满足 r o o t ∗ k + i < n root*k+i<n rootk+i<n(其中, n n n是整棵树的结点数, i ∈ [ 1 , k ] i \in [1,k] i[1,k])。

class Solution {
    
    
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param k int整型 表示完全k叉树的叉数k
     * @param a int整型vector 表示这棵完全k叉树的Bfs遍历序列的结点编号
     * @return long长整型
     */
    long long tree2(long long k, vector<int>& a) {
    
    
        queue<long long> q;
        while(!q.empty()) q.pop();
        q.push(0);
        long long n=a.size();long long ans=0;
        while(!q.empty())
        {
    
    
            long long cur=q.front();q.pop();
            for(int i=1;i<=k;++i)
            {
    
    
                if(cur*k+i>=n) break;
                ans+=a[cur]^a[cur*k+i];
                q.push(cur*k+i);
            }
        }
        return ans;
    }
};

D:数据分析

  这道题求解的是各个长度的子数组中最高销量的最小值。不断枚举各个子区间,然后求解这个区间的最大值,这样做的复杂度是 O ( n 3 ) O(n^3) O(n3),不可取。
  我们先明确一个规律,对于一个数 x x x来说,如果我们能找到第一个比 x x x大的左右位置 l m a x , r m a x lmax,rmax lmax,rmax,那么也就是意味着我们能找到长度为 [ 1 , r m a x − l m a x − 1 ] [1,rmax-lmax-1] [1,rmaxlmax1]中的各个长度子数组,满足 x x x是这个子数组的最大值。
  我们得出了以数组中每个位置元素为最大值的最大数组长度,排个序,则在相同长度的数组下,键值小的元素就是答案。
  现在的问题就是求解如何找到 l m a x , r m a x lmax,rmax lmax,rmax,我们可以用单调栈的方式来在 o ( n ) o(n) o(n)的时间内求解出来。

const int maxn=1e5+100;
int lmax[maxn],rmax[maxn];
struct Node{
    
    
    int val,len;
    void Init(int v,int l) {
    
    val=v;len=l;}
    bool operator < (const Node a)const 
    {
    
    
        if(val==a.val) return len>a.len;
        return val<a.val;
    }
}node[maxn];
class Solution {
    
    
public:
    /**
     * 找到所有长度子数组中最大值的最小值
     * @param numbers int整型vector 牛牛给出的数据
     * @return int整型vector
     */
    vector<int> getMinimums(vector<int>& n) {
    
    
        int size=n.size();
        stack<int> s;while(!s.empty()) s.pop();
        for(int i=0;i<size;++i)
        {
    
    
            if(s.empty() || n[i]<=n[s.top()]) s.push(i);
            else{
    
    
                while(!s.empty())
                {
    
    
                    if(n[i]<=n[s.top()]) break;
                    rmax[s.top()]=i-1;s.pop();
                }
                s.push(i);
            }
        }
        while(!s.empty()) {
    
    rmax[s.top()]=size-1;s.pop();}
        for(int i=size-1;i>=0;--i)
        {
    
    
            if(s.empty() || n[i]<=n[s.top()]) s.push(i);
            else{
    
    
                while(!s.empty())
                {
    
    
                    if(n[i]<=n[s.top()]) break;
                    lmax[s.top()]=i+1;s.pop();
                }
                s.push(i);
            }
        }
        while(!s.empty()) {
    
    lmax[s.top()]=0;s.pop();}
        for(int i=0;i<size;++i)  node[i].Init(n[i],rmax[i]-lmax[i]+1);
        sort(node,node+size);
        int loc=0;vector<int> ans;ans.clear();
        for(int i=0;i<size;++i)
            while(node[i].len>loc) ans.push_back(node[i].val),loc++;
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/CUMT_William_Liu/article/details/111238800