zoukankan      html  css  js  c++  java
  • 寻找假银币

    寻找假银币是一个非常有趣的智力题目,寻找假银币的大意如下:

      现在有8枚银币,其中一枚是假币。但是,从外观和做工上无法分辨哪枚是真币哪枚是假币,只知道假币的重量要比真币稍轻。则要求仅用一个天平,如何以最少的步骤寻找到假银币?

    1. 寻找假银币算法

    可以采用递归分治的思想来求解这个问题,操作步骤如下:

    (1)首先为每个银币编号,然后可以将所有的银币等分为两份,放在天平的两边。

    (2)因为假银币的分量较轻,因此天平较轻的一侧中一定包含假银币。

    (3)再将较轻的一侧中的硬币等分为两份,重复上述做法。

    (4)直到剩下两枚硬银币,可用天平直接找出假银币来。

    这种方法在银币个数比较多时便显出了优势。照此思路编写寻找假银币问题求解的算法如下:

        static int falseCoin(int coin[],int low,int high){
            int i,sum1,sum2;
            int re=0;
            sum1=sum2=0;
            if(low+1==high){
                if(coin[low]<coin[high]){
                    re=low+1;
                    return re;
                }else{
                    re=high+1;
                    return re;
                }
            }
            //如果n是偶数
            if((high-low+1)%2==0){
                //记录前一半的重量
                for(i=low;i<low+(high-low+1)/2;i++){
                    sum1+=coin[i];
                }
                //记录后一半的重量
                for(i=low+(high-low+1)/2;i<=high;i++){
                    sum2+=coin[i];
                }
                if(sum1<sum2){
                    re = falseCoin(coin,low,low+(high-low+1)/2-1);
                }else if(sum1>sum2){
                    re = falseCoin(coin,low+(high-low+1)/2,high);
                }
            }else{        //n为奇数
                //记录前一半的重量
                for(i=low;i<low+(high-low)/2;i++){
                    sum1+=coin[i];
                }
                //记录后一半的重量
                for(i=low+(high-low)/2+1;i<=high;i++){
                    sum2+=coin[i];
                }
                if(sum1<sum2){
                    re = falseCoin(coin,low,low+(high-low)/2-1);
                }else if(sum1>sum2){
                    re = falseCoin(coin,low+(high-low)/2+1,high);
                }else{
                    re=low+(high-low)/2+1;
                    return re;
                }
            }
            return re;
        }

    2. 寻找假银币求解完整代码

    package com.cn.suanfaquti;
    
    import java.util.Scanner;
    
    public class FalseCoin {
        static final int MAXNUM=30;    //最大硬币数
        static int falseCoin(int coin[],int low,int high){
            int i,sum1,sum2;
            int re=0;
            sum1=sum2=0;
            if(low+1==high){
                if(coin[low]<coin[high]){
                    re=low+1;
                    return re;
                }else{
                    re=high+1;
                    return re;
                }
            }
            //如果n是偶数
            if((high-low+1)%2==0){
                //记录前一半的重量
                for(i=low;i<low+(high-low+1)/2;i++){
                    sum1+=coin[i];
                }
                //记录后一半的重量
                for(i=low+(high-low+1)/2;i<=high;i++){
                    sum2+=coin[i];
                }
                if(sum1<sum2){
                    re = falseCoin(coin,low,low+(high-low+1)/2-1);
                }else if(sum1>sum2){
                    re = falseCoin(coin,low+(high-low+1)/2,high);
                }
            }else{        //n为奇数
                //记录前一半的重量
                for(i=low;i<low+(high-low)/2;i++){
                    sum1+=coin[i];
                }
                //记录后一半的重量
                for(i=low+(high-low)/2+1;i<=high;i++){
                    sum2+=coin[i];
                }
                if(sum1<sum2){
                    re = falseCoin(coin,low,low+(high-low)/2-1);
                }else if(sum1>sum2){
                    re = falseCoin(coin,low+(high-low)/2+1,high);
                }else{
                    re=low+(high-low)/2+1;
                    return re;
                }
            }
            return re;
        }
        public static void main(String[] args) {
            int[] coin=new int[MAXNUM];
            int i,n,result;
            System.out.println("分治法求解假银币问题!");
            System.out.print("请输入银币总个数:");
            Scanner input = new Scanner(System.in);
            n=input.nextInt();
            System.out.print("请输入银币重量:");
            for(i=0;i<n;i++){
                coin[i]=input.nextInt();
            }
            result = falseCoin(coin,0,n-1);    //求解
            System.out.printf("在上述%d个银币中,第%d个银币是假的!",n,result);
        }
    
    }

    程序运行结果如下:

    分治法求解假银币问题!
    请输入银币总个数:7
    请输入银币重量:2 2 1 2 2 2 2
    在上述7个银币中,第3个银币是假的!
  • 相关阅读:
    BUAA OO Unit1 表达式求导
    中介者模式
    命令模式
    观察者模式
    解释器模式
    策略模式
    迭代器模式
    模板方法模式
    代理模式
    桥接模式
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4513733.html
Copyright © 2011-2022 走看看