牛客巔峰賽S2第2場題解(青銅白銀組)

ACJavaBear發表於2020-11-20

牛客巔峰賽青銅白銀組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。

相關文章