士兵分子彈算法——java實現

題目

在某次實彈射擊訓練中,班長將十個戰士圍成一圈發子彈。首先,班長給第一個戰士10顆,第二個戰士2顆,第三個戰士8顆,第四個戰士22顆,第五個戰士16顆,第六個戰士4顆,第七個戰士10顆,第八個戰士6顆,第九個戰士14顆,第十個戰士20顆。然後按如下方法將每個戰士手中的子彈進行調整:所有的戰士檢查自己手中的子彈數,如果子彈數爲奇數,則向班長再要一顆。然後每個戰士再同時將自己手中的子彈分一半給下一個戰士(第10 個戰士將手中的子彈分一半給第1個戰士)。
問需要多少次調整後,每個戰士手中的子彈數都相等?每人各有多少顆子彈?
要求輸出每輪調整後各戰士手中的子彈數。

思路

這題難度一般,就是煩,我也沒能想到更好的算法。首先就有一個很重要的問題就是檢驗每個戰士是否相等。如果不加限制的判斷的話就會導致出現O(n^2)的可能,所以我在這裏用了一個總子彈數對士兵數取模的操作,這樣可以保證只有在值爲0的時候是可以出現平均分的情況的,這樣可以大大減少循環的次數。之後就是比較平常的操作了。

代碼

public static void fenZiDan(int[]shibing){
        int total = 0;//子彈總數
        int times = 0;//次數
        int[] temp = new int[shibing.length];//臨時記錄士兵第一次交出子彈後的數量
        for(int i=0;i<shibing.length;i++){
            total+=shibing[i];
        }
        while(true){//循環執行任務
            times++;
            for(int i=0;i<shibing.length;i++){
                if(shibing[i]%2!=0){
                    total++;//向班長要一顆子彈
                    temp[i] = (shibing[i]+1)/2;
                }else {
                    temp[i] =shibing[i]/2;
                }
            }
            for(int i=0;i<shibing.length;i++){
                if(i>0) {
                    shibing[i] = temp[i - 1] + temp[i];
                }else {
                    shibing[i] = temp[i]+temp[temp.length-1];
                }
                if(i!=shibing.length-1){
                    System.out.print(shibing[i]+" ");
                }else {
                    System.out.println(shibing[i]+" ");
                }
            }

            if(total%shibing.length==0){//表示可以平均分,是子彈都相等的必要不充分條件,只有此時纔會進行檢查
                boolean isEnd = true;
                for(int i=1;i<shibing.length;i++){
                    if(shibing[0]!=shibing[i]){
                        isEnd = false;
                        break;
                    }
                }
                if(isEnd){
                    break;
                }
            }
        }
        System.out.println("總共進行了"+times+"次");
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章