牛客巅峰赛S2第2场题解(青铜白银组)

本文是牛客网巅峰赛S2第二场青铜白银组的题目解析,包含三道算法题,涉及糖果分配、木棒分割和完全k叉树还原问题。解析中提供了两种解题思路,包括找规律、二分以及斐波那契数列的应用。
摘要由CSDN通过智能技术生成

牛客巅峰赛青铜白银组S2第2场

第一题

题意:

牛牛是个非常热心的人,所以他有很多的朋友。这一天牛牛跟他的n个朋友一起出去玩,在出门前牛牛的妈妈给了牛牛k块糖果,牛牛决定把这些糖果的一部分分享给他的朋友们。由于牛牛非常热心,所以他希望他的每一个朋友分到的糖果数量都比牛牛要多(严格意义的多,不能相等)。牛牛想知道他最多能吃到多少糖果?

示例1

输入:

2,10

输出:

2

说明:

牛牛可以分给他的两个朋友各4个糖果,这样他能吃到2个糖果,这样能保证他的每个朋友的糖果数都比他多,不存在牛牛能吃到3个或者以上糖果的情况
示例2

输入:

3,11

输出:

2

说明:

牛牛可以分给他的3个朋友各3个糖果,这样他能吃到2个糖果,这样能保证他的每个朋友的糖果数都比他多,不存在牛牛能吃到3个或者以上糖果的情况
备注:
对于百分之30的数据:1≤n≤100,n≤k≤100
对于百分之100的数据:1≤n≤1e18,n≤k≤1e18
函数有两个long long型参数
第一个参数代表题目中的n
第二个参数代表题目中的k
题解:

第一种解法:

找规律

  • 当糖平均分给每个人(包括自己),剩下的糖数恰好等于朋友数时,这个时候自己不用分享出自己的糖,所以返回平均数。
  • 当剩下的糖数小于朋友数时,自己一定要分出一颗糖。
import java.util.*;
public class Solution {
    public long Maximumcandies (long n, long k) {
        long ave = k / (n + 1) ;
        long last = k % (n+1);
        if(last == n) return ave;
        return ave-1;
    }
}

第二种解法:

二分

import java.util.*;


public class Solution {
    public long Maximumcandies (long n, long k) {
        long left = 0,right = k,res = 0;
        while(left <= right){
            long mid = (left + right)/ 2;
            if(check(n,k,mid)){
                res = mid;
                left = mid+1;
            }else{
                right = mid - 1;
            }
        }
        return res;
    }
    public boolean check(long n,long k,long mid){
        return (k - mid) / n > mid;
    }
}

第二题

题意:

牛牛有一根长度为 a a a ( 3 3 3 a a a 1 e 18 1e18 1e18)的木棒,现在牛牛想将木棒分成一些段(每段木棒长度必须为整数),使得分隔后的木棍中,任意三段都不能构成三角形,牛牛想知道木棒最多被分成几段呢?

示例1

输入:

5

输出:

3

说明:

可以分成1 1 3三段
题解:

要求不能构成三角形,我们知道,构成三角形的条件为两边之和大于第三边,即不构成三角形的条件为两边之和小于等于第三边。同时题目要求我们最多分成多少段,也就是说只要卡住边界条件两边之和等于第三边做文章,且可以推出两短边之和等于第三边。于是我们可以想到斐波那契数列

import java.util.*;
public class Solution {
    public int stick (long a) {
        long[] s = new long[100];
        s[0] = 1;
        s[1] = 1;
        for(int i = 2; i < s.length; i++){
            s[i] = s[i-1] + s[i-2];
        }
        long ans = 0;
        for(int i = 0; i < s.length; i++){
            ans += s[i];
            if(ans > a) return i;
        }
        return -1;
    }
}

第三题:

题意:

系统中有一棵 n n n个点的完全 k k k叉树,现给出它的 B F S BFS BFS层序遍历序列 a i a_i ai即从根节点开始,每一层从左向右遍历),请你还原这棵树,并返回加密后的答案。 答案加密方法:所有边两个端点异或的和。

示例1

输入:

2,[1,2,3,4,5]

输出:

18

说明:

树边为(1, 2), (1, 3), (2, 4), (2, 5),加密过程为(1^2)+(1^3)+(2^4)+(2^5),答案为18。
示例2

输入:

3,[1,2,3,4,5]

输出:

17

说明:

树边为(1, 2), (1, 3), (1, 4), (2, 5),加密过程为(1^2)+(1^3)+(1^4)+(2^5),答案为17。
备注
数据满足:1≤n,k≤10e5,1≤ai≤10e9
题解:

由于数组本来就是由 B F S BFS BFS搜索这棵完全 k k k叉树得到的,所以它一定是

  • 先进根节点
  • 弹出根节点并把子节点加入

所以直接根据 B F S BFS BFS定义来做就好了。

import java.util.*;
public class Solution {
    public long tree2 (int k, int[] a) {
        int n = a.length;
        int curPos = 1;    //当前位置
        long res = 0;	   //结果
        for(int i = 0; i < n; i++){
            if(curPos >= n) break;         //当前位置超出了数组范围,直接跳出循环
            for(int j = 0; j < k; j++){    //由于是k叉树,枚举后面k个点
                if(curPos < n)				//没有超出范围的情况下
                {
                    res += (a[i] ^ a[curPos]);		//计算结果
                    curPos++;					//向后移动一位
                }
            }
        }
        return res;
    }
}

欢迎关注我的公众号ACJavaBear,一起学Java。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值