牛客编程巅峰赛S2第2场 - 钻石&王者 ABC

牛牛切木棒

https://ac.nowcoder.com/acm/contest/9224/A

ABC题解
A牛牛切木棒
任意三个不能构成三角形,一定是:1,1,2,3,5……斐波那契数列,刚好任意三个一定满足a+b<=c

class Solution {
public:
    /**
     * 
     * @param a long长整型 木棒的长度
     * @return int整型
     */
    int stick(long long a) {
        // write code here
        if(a<=3)return 2;
        int nm=2;
        long long a1=1,a2=1,tmp;
        a-=2;
        while(a>0){
            tmp=a1+a2;
            a1=a2;
            a2=tmp;
            a-=tmp;
            if(a<0)break;
            nm++;
        }
        return nm;
    }
};

BTree II
比赛时写麻烦了,还分层写了下。。

其实我们观察发现:每个点的儿子节点刚好是k个,而且是连续的,

1号点的儿子是2,3,4,

2号点的儿子是5,6,7,

依此类推。

我们只需要枚举点,枚举其K个儿子,然后让儿子点序号加上K即可。

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

C:数据分析
从问题本质去想:

连续K子数组最大值,的最小值。

对于任意一个数a[i],

他做为可以最大值的区间假如是:[L,R],即max([a[L]->a[R]).

于是,当K小于等于R-L+1时,a[i]可以对最终最小值产生贡献。

到这里问题就解决了!

只要快速求出每个数做为最大值维护的区间即可。

这是单调栈的经典问题。

class Solution {
public:
    /**
     * 找到所有长度子数组中最大值的最小值
     * @param numbers int整型vector 牛牛给出的数据
     * @return int整型vector
     */
    int a[100007];
    int s[100007],p,l[100007],r[100007];
    vector<int> getMinimums(vector<int>& numbers) {
        // write code here
        int n =numbers.size();
        for(int i=1;i<=n;i++)a[i]=numbers[i-1];
        p=0;
        for(int i=1;i<=n;i++){
            while(p&&a[i]>=a[s[p]])p--;
            l[i]=s[p];
            s[++p]=i;
        }
        p=0;s[p]=n+1;
        for(int i=n;i>=1;i--){
            while(p&&a[i]>=a[s[p]])p--;
            r[i]=s[p];
            s[++p]=i;
        } 
        vector<int>ans;
        for(int i=1;i<=n;i++)ans.push_back(1e9+7);
        for(int i=1;i<=n;i++){
            int id=r[i]-l[i]-1;
            ans[id-1]=min(ans[id-1],a[i]);
        }
        for(int i=n-2;i>=0;i--)ans[i]=min(ans[i+1],ans[i]);
        return ans;
    }
};
全部评论

相关推荐

11-28 17:48
中山大学 C++
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-24 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
评论
3
收藏
分享
牛客网
牛客企业服务