【牛客刷题】有假币;在一堆硬币中有一个假币,要求在最短时间内最多称量几次可以找出这个假币。(超详细题解)

        试题链接:有假币__牛客网 

        先贴代码:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            //输入硬币数n:
            int n = scanner.nextInt();
            if (n == 0){ //当假币为0时,输入结束,退出循环
                break;
            }
            if (n == 1){ //当假币为1时,不用称量就能知道它是否是假币(因为假币比真币轻)
                System.out.println(0);
            }else if (n <= 3){ //当假币数小于等于3时,只要称量一次就可以
                System.out.println(1);
            }else { //当假币数量大于3时:
                int count = 1; //count为称量次数
                while (n > 3){
                    if (n % 3 == 0){
                        n /= 3;
                    }else {
                        n = n / 3 + 1;
                    }
                    count++;
                }
                System.out.println(count);
            }
        }
    }
}

        解题思路:

        题目要求我们要在最快时间内找出假币,并且给我们一个可以称量的天平,还告诉我们假币比真币要轻,那么此时很显然,我们需要将这些硬币分成相同的几堆,再对这几堆硬币分别进行称量,重量轻的那一堆就是假币所在的那一堆,再将轻的那一堆分开,继续上述步骤,就可以找出那一枚假币了。

        可是问题来了,我们要分几堆呢?是分成两堆还是分成三堆亦或者分更多堆呢?再来看看题目的要求:想让我们在最快时间内找出来。那么就说明我们称量次数是越少越好,因为次数一多,难免要花费更多的时间。所以就应该在分两堆或者三堆中进行选择;为什么不选更多的堆数?

        假如我们分成平均四堆,假币就在这四堆当中,那么我们需要称量几次得知假币的位置?两次!因为天平每次只能称量两堆硬币。而如果分成两堆或者三堆就只要称量一次就可以得知假币的位置。可是最后到底是分两堆还是三堆呢?因为若是分两堆,每次称量过后只能排除一半,而分三堆的话每一次称量后可以排除三分之二,相对来说更加高效一点。

        确定分三堆后,接下来就是分硬币数 n 情况来讨论:
        1、当n == 1时:只有一个硬币,无法上天平称量,但是可以直接判断是否为假币,所以是0次。
        2、当n <= 3时:此时只要称量一次就可以得知假币的位置。
        3、当n > 3时:需要将这些硬币分成三堆,分法是,能被3整除的,分成均匀的三堆,不能被3整除的,先将n除以3,得到的数无视小数取整,这个数是前两堆,剩下的为第三堆;比较的时候先比较前两堆,如果前两堆重量相等,那么假币就在第三堆里,再按照前面的方法,将第三堆也分为三堆,继续比较。

猜你喜欢

转载自blog.csdn.net/weixin_56960711/article/details/125103394