减治法解决假币问题plus C++代码

本文介绍了一种使用减治法查找假币的算法,通过将硬币分为三组进行比较,逐步缩小疑似假币的范围,最终确定假币位置。代码实现了递归查找过程,适用于假币重量未知的情况。

减治法解决假币问题plus

以下代码是使用减治法查找假币,其中假币与真币的重量关系未知。

#include <iostream>
#include <stdlib.h>

using namespace std;

int m=0;          //真币质量

int Coin(int coin[], int n, int low, int high){ //在a[low]~a[high]中查找假币
    int num1, num2, num3;        //存储三组硬币的个数
    int add1=0, add2=0, add3=0;             //add1和add2存储前两组硬币的重量和
    //cout << m << endl;
    if(n==1)
        return low+1;
    if(n==2){           //递归结束的条件
        //cout << "执行了判定条件:符合条件,可以结束!" << endl;
        if(coin[low]!=m)
            return low+1;   //返回的是序号,即下标加1
        else
            return high+1;
    }

    if(n%3==0)          //3组硬币的个数相同
        num1=num2=n/3;
    else                //前两组有n/3枚硬币
        num1=num2=n/3+1;
    num3=n-num1-num2;   //第三组硬币

    for(int i=0; i<num1; i++)           //计算第一组硬币的重量和
        add1 = add1+coin[low+i];
    for(int i=num1; i<num1+num2; i++)   //计算第二组硬币的重量和
        add2 = add2+coin[low+i];
    for(int i=num1+num2;i<n;i++)
        add3 = add3+coin[low+i];
    if(add1!=add2){
        if(num3!=0) m = add3/num3;
        if(add1!=m*num1)
            return Coin(coin,num1, low, low+num1-1);    //在第一组查找,下标范围是low ~ low+num1-1
        else
            return Coin(coin,num2, low+num1, low+num1+num2-1);  //在第二组查找,下标范围是low+num1 ~ low+num1+num2-1
        }
    else{                   //在第三组查找,下标范围是low+num1+num2 ~ high
        if(num1!=0) m = add1/num1;
        return Coin(coin,num3, low+num1+num2, high);
    }
}

int main()
{
    int n;
    cout << "请输入硬币个数:";
    cin >> n ;
    int coin[n];

    //假币的随机生成
    for(int i=0; i<n; i++)
        coin[i]=2;      //所有硬币的重量为 1
    int x = rand()%n;   //生成0到n的随机数
    coin[x] = 1;    //第x枚硬币为假币

    int a = Coin(coin, n,0,n-1);
    cout << "第" << a << "枚硬币是假币。"<< endl;

    cout << "所有硬币的质量依次为:" << endl;
    for(int i=0; i<n; i++)
        cout << coin[i] << " ";
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值