Java 算法之八枚硬币

有几天没有发文章了,感觉再不写点东西又要堕落了,所以今天又给大家带来一道算法,八枚硬币,多的不说了我们直接进入今天的主题。

算法描述:

说明:现有八枚硬币a, b, c, d, e, f, g, h已知其中一枚是假币,其重量不同于真币,但不知是较轻或较重,如何使用天平以最少的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重。


一、解题步骤

1、解读题目

首先我们先读一遍题,题目给我们的要求我们大概知道,是从八枚硬币中找到哪一枚是假的,并且确定是比真的重还是轻,如果就这些还是比较简单的。但是需要步骤最少,这个就需要我们慢慢想一想了。

2、解题思路

原数据:a , b , c , d , e , f , g , h

按最常规的想法取出一枚和其他的每一枚比较,这种运气好点也需要两步,

a - b (a 大于或者小于 b)
a - c (a 大于或者小于 c)
如果得到的结果是上面这样,那么恭喜你手上那一枚,就是假币。
a - b (a 大于或者小于 b)
a - c (a 等于 c)
这样 b 就是假币,其他也一样但是如果你是非酋可能会比七次最后一次才能确定。

我看了一下其他文章,他们很多都是用的一种 3 3 2 分组的形式来解决的。

分组 : a b c | d e f | g h
a b c - d e f
如果相等,表示都是真的,g,h一定是假的,从这六个随便取一个,然后和后面两个比较。
不相等,g,h一定是真的,这时候在吧 a b c d e f 两两分组然后和 g,h 比较找出不一样的一组
这种比较非酋的人也可能要 6 步。

还有一些其它解法,我就不都写出来了,有兴趣的小伙伴可以看看其他博客写的。

我和他们的想法一样都使用了分组,但用的是 2 2 2 2 分组的形式。

分组 :a b | c d | e f | g h
a b - c d
如果相等那么假币一定在 e f g h 当中,不相等就在 a b c d 当中
我们只需要取正确的一组 a b c d (假如这一组都是真币)当中随便两枚,这里就取 a b
a b - e f
如果相等那么假币一定在 g h当中 ,不相等就在 e f 当中
这时我们只需要取一枚我们确定的真币和不相等的一组比较我们用的是相对思想,两组比较一组都是真币另一组必然含假币,不需要在使用天平
我们这个方法非酋最多也只需要 4 步。

在这里插入图片描述

二、代码

欢迎大家来到最不喜欢的看代码环节,这次代码判断比较多,但是都很相似,配合我的解题思路,看懂应该不成问题。

public class Test {

    public static void main(String[] args) {

       //现有八枚银币a, b, c, d, e, f, g, h,已知其中一枚是假币,其重量不同于真币,但不知是较轻或较重,如何使用天平以最少
       //的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重。
        int []temp = {10,10,10,10,10,10,10,11};
        //我们分为两组    4       4
        //在吧每组分为  2    2  2    2 各自比较 这一步能找出假币在那一边(那个4里面)

        //如果相等假币在另一组 否则在自己这组
        if((temp[0] + temp[1]) == (temp[2] + temp[3])){  //第一次
            //假币必然在  temp[4] temp[5] temp[6] temp[7] 之中
            //再用对的一组  和 不正确一组的随便一个 1组 在进行比较
            if((temp[0] + temp[1]) == (temp[4] + temp[5])){  //第二次
                //这样假币一定在 temp[6] 和 temp[7] 之中
                if(temp[0] != temp[6]){  //第三次  最少需要次数
                    //假币必然是temp[6]
                    if(temp[0] > temp[6]){
                        System.out.println("假币是:" + temp[6] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[6] + "-并且比真币重");
                    }
                }

               if(temp[0] != temp[7]){  //第四次 最多需要次数(因为是天平所以第三步如果没有假币,执行这个循环相当于在使用了一次天平)
                   //假币必然是temp[7]
                   if(temp[0] > temp[7]){
                       System.out.println("假币是:" + temp[7] + "-并且比真币轻");
                   }else {
                       System.out.println("假币是:" + temp[7] + "-并且比真币重");
                   }
               }

            }else if((temp[0] + temp[1]) != (temp[4] + temp[5])){
                //这样假币一定在 temp[4] 和 temp[5] 之中
                if(temp[0] != temp[4]){  //第三次  最少需要次数
                    //假币必然是temp[4]
                    if(temp[0] > temp[4]){
                        System.out.println("假币是:" + temp[4] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[4] + "-并且比真币重");
                    }
                }

                if(temp[0] != temp[5]){  //第四次 最多需要次数
                    //假币必然是temp[5]
                    if(temp[0] > temp[5]){
                        System.out.println("假币是:" + temp[5] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[5] + "-并且比真币重");
                    }
                }
            }
        }else if((temp[0] + temp[1]) != (temp[2] + temp[3])){
            //假币必然在  temp[0] temp[1] temp[2] temp[3] 之中
            if((temp[4] + temp[5]) == (temp[0] + temp[1])){
                //这样假币一定在 temp[2] 和 temp[3] 之中
                if(temp[4] != temp[2]){
                    //假币必然是temp[2]
                    if(temp[4] > temp[2]){
                        System.out.println("假币是:" + temp[2] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[2] + "-并且比真币重");
                    }
                }

                if(temp[4] != temp[3]){
                    //假币必然是temp[3]
                    if(temp[4] > temp[3]){
                        System.out.println("假币是:" + temp[3] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[3] + "-并且比真币重");
                    }
                }

            }else if((temp[4] + temp[5]) != (temp[0] + temp[1])){
                //这样假币一定在 temp[0] 和 temp[1] 之中
                if(temp[4] != temp[0]){
                    //假币必然是temp[0]
                    if(temp[4] > temp[0]){
                        System.out.println("假币是:" + temp[0] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[0] + "-并且比真币重");
                    }
                }

                if(temp[4] != temp[1]){
                    //假币必然是temp[1]
                    if(temp[4] > temp[1]){
                        System.out.println("假币是:" + temp[1] + "-并且比真币轻");
                    }else {
                        System.out.println("假币是:" + temp[1] + "-并且比真币重");
                    }
                }
            }
        }
    }
}

结果

假币是:11-并且比真币重

小结

算法这个东西我不能说我的就是最简,因为可能有很多我没想到的细节可以减少步骤,所以看作者的文章就当是一种思路,大家也多想一想有没有其他更简单的方法,如果有先就来给作者留言或者私信,让作者早点改掉,挽留一点作者的脸面^ 0 ^。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值