士兵分子弹算法——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+"次");
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值