三分法解决假币问题(JAVA)

一,问题描述

有n个硬币,其中有一枚是假币,假币比真币要轻,现有一天平,通过比较找出假币。


二,三分法思路

1.将硬币分为三堆,每堆按照n/3向上取整个硬币来分配(主要分配前两堆,第三堆就是剩下的)

2.比较第一堆和第二堆硬币重量

若重量相等,则在第三堆中找假币,重复第一步

        若第一堆比第二堆重,则在假币在第二堆中,去第二堆中找假币,重复第一步

        若第二堆比第一堆重,则在假币在第一堆中,去第一堆中找假币,重复第一步

package algorithm;

import sun.applet.Main;

public class Test {
    //三分法找假币
    /**
     * left表示所要查找的数组中第一个元素在n个硬币中的数组下标
     * right表示所要查找的数组中最后一个元素在n个硬币中的数组下标
     * 输入:硬币数组a[]
     * 输出:假币在数组中对应的下标
     *
     */
    int find3(float a[],int left,int right){
        int n=right-left+1;//硬币个数
        int m1=left+upint(n)-1;//第一堆硬币的最后一个硬币在n个硬币中对应的下标
        int m2=left+2*upint(n)-1;//第二堆硬币的最后一个硬币在n个硬币中对应的下标

        //前两堆硬币等重,则在第三堆中找假币
        if (weight(a,left,m1)==weight(a,m1+1,m2)) {
            System.out.println("左右相等!");
            System.out.print("left="+left+"  ");
            System.out.print("right="+right+"  ");
            System.out.print("m1="+m1+"  ");
            System.out.println("m2="+m2+"  ");
            if ((right - m2) == 1)
                return right;
            else {
                left = m2 + 1;
                return find3(a, left, right);

            }
        }

        //第一堆比第二堆重,则在第二堆中找假币
        if (weight(a,left,m1)>weight(a,m1+1,m2)) {
            System.out.println("左大于右!");
            System.out.print("left="+left+"  ");
            System.out.print("right="+right+"  ");
            System.out.print("m1="+m1+"  ");
            System.out.println("m2="+m2+"  ");
            if ((m2 - m1) == 1)
                return m2;
            else {
                left = m1 + 1;
                right = m2;
                return find3(a, left, right);
            }
        }

        //第二堆比第一堆重,则在第一堆中找假币
        if (weight(a,left,m1)<weight(a,m1+1,m2)){
            System.out.println("左小于右!");
            System.out.print("left="+left+"  ");
            System.out.print("right="+right+"  ");
            System.out.print("m1="+m1+"  ");
            System.out.println("m2="+m2+"  ");
            if(m1==left){
                return left;
            } else {
                right=m1;
                return find3(a,left,right);
            }
        }
        return 0;


    }
    //计算硬币重量,即数组元素和
    float weight(float a[],int left,int right){
        float sum=0;
        for(int i=left;i<=right;i++){
            sum+=a[i];
        }
        return sum;
    }

    //对 n/3 的值向上取整
    int upint(int n){
        if((n%3)==0)
            return n/3;
        else return n/3+1;
    }



}


class test1{
    public static void main(String args[]){
        Test t=new Test();
        float a[]={1,1,1,1,1,1,1,1,1,1,1,0.4f,1,1,1};
        System.out.println("硬币个数为:"+a.length);
        System.out.println("硬币总重量为:"+t.weight(a,0,a.length-1));
        System.out.println("假币在数组中的下标为:"+t.find3(a,0,a.length-1));

    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值