牛客巅峰赛青铜白银组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; } }
第二题
题意:
牛牛有一根长度为 (≤≤)的木棒,现在牛牛想将木棒分成一些段(每段木棒长度必须为整数),使得分隔后的木棍中,任意三段都不能构成三角形,牛牛想知道木棒最多被分成几段呢?
示例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; } }
第三题:
题意:
系统中有一棵个点的完全叉树,现给出它的层序遍历序列即从根节点开始,每一层从左向右遍历),请你还原这棵树,并返回加密后的答案。 答案加密方法:所有边两个端点异或的和。
示例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
题解:
由于数组本来就是由搜索这棵完全叉树得到的,所以它一定是
- 先进根节点
- 弹出根节点并把子节点加入
所以直接根据定义来做就好了。
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; } }