假硬币问题求解

题目描述:

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

解法:单就求假币的问题是不难,但问题限制使用最少的比较次数,所以我们不能以单纯的回圈比较来求解,我们可以使用决策树(decision tree),使用分析与树状图来协助求解。一个简单的状况是这样的,我们比较a+b+c与d+e+f ,如果相等,则假币必是g或h,我们先比较g或h哪个较重,如果g较重,再与a比较(a是真币),如果g等于a,则g为真币,则h为假币,由于h比g轻而 g是真币,则h假币的重量比真币轻。

这个思路是直接用的逻辑推理的方法。相关代码如下所示:

void compare(int coins[], int i, int j, int k)
{
    if(coins[i] > coins[k])
    {
        printf("\n假币 %d 较重", i+1);
    }
    else
    {
        printf("\n假币 %d 较轻", j+1);
    }
}

void eightcoins(int coins[])
{
    if (coins[0] + coins[1] + coins[2] == coins[3] + coins[4] + coins[5])
    {
        if (coins[6] > coins[7])
        {
            compare(coins,6,7,0);
        }
        else
        {
            compare(coins,7,6,0);
        }
    }
    else if (coins[0] + coins[1] + coins[2] > coins[3] + coins[4] + coins[5])
    {
        if (coins[0]+coins[3] == coins[1]+coins[4])
        {
            compare(coins,2,5,0);
        }
        else if (coins[0]+coins[3] > coins[1]+coins[4])
        {
            compare(coins,0,4,1);
        }
        else if(coins[0]+coins[3] < coins[1] + coins[4])
        {
            compare(coins,1,3,0);
        }
    }
    else if(coins[0] + coins[1] + coins[2] < coins[3] + coins[4] + coins[5])
    {
        if(coins[0]+coins[3] == coins[1]+coins[4])
        {
            compare(coins, 5, 2, 0);
        }
        else if(coins[0]+coins[3] > coins[1]+coins[4])
        {
            compare(coins, 3, 1, 0);
        }
        if(coins[0]+coins[3] < coins[1]+coins[4])
        {
            compare(coins, 4, 0, 1);
        }
    }
}

当然,这个问题的求解也可以利用异或的特性:两个相同的数异或以后为0。再加上利用“二分”的思想,效率可以提高不少。利用这种方法,在比较好理解的同时,也还可以将该问题进行扩展:void FalseCoins(int coins[],int start,int end)。这样,就可以不仅仅是解决固定的8枚硬币问题了。具体代码如下所示:

void myEightCoins(int coins[])
{
    int start,mid,end;
    int sum1,sum2;
    int right;

    start = 0;
    end   = 7;
    mid   = (start+end)/2;

    int i;
    sum1 = sum2 = 0;

    while (start < end - 1)
    {
        sum1 = coins[start];
        for (i = start + 1; i <= mid; i++)
        {
            sum1 = sum1 ^ coins[i];
        }
        sum2 = coins[end];
        for (i = end - 1; i > mid; i--)
        {
            sum2 = sum2 ^ coins[i];
        }
        if (sum1 == 0)
        {
            right = start;
            start = mid + 1;
            mid   = (start+end)/2;
        }
        if (sum2 == 0)
        {
            right = end;
            end = mid;
            mid = (start+end)/2;
        }
    }

    if (coins[start] > coins[end])
    {
        compare(coins,start,end,right);
    }
    else
    {
        compare(coins,end,start,right);
    }
}

假硬币问题求解

时间: 2024-11-05 17:28:42

假硬币问题求解的相关文章

【数据结构】分治算法求解假硬币问题

问题描述: 概念 分治算法的基本思想是将一个大的复杂的问题分解成多个小的.容易解决的问题,通过解决这些小问题进而解决这个大问题. 使用分治算法需要待求解问题能够简化为若干个小规模的相同的问题,通过逐步划分,达到一个易于求解的阶段,而直接进行求解,在程序中可以使用递归方法来进行求解. 哈哈,说起来很抽象,举个例子就好理解了. 一个袋子里有n个硬币,其中一枚是假币,并且假币和真币一模一样,仅凭肉眼无法区分,仅知道假币比真币轻一些,请问如何查找到假币? 分治算法: 我们可以这样做: 将这n个硬币分成两

poj1029(找假硬币)模拟

题意:给n个硬币,其中有一个硬币和其他的硬币重量不一样,给出k次比较重量的结果.问是否可以将假硬币找出来. 解法:判断一个硬币是真币的方法(满足其一): 1.这个硬币出现过在=的两边 2.既出现在小于的一边过,也出现在大于的一边过. 如果排除这些硬币后只剩下一个,那么假币就是剩下的那个,否则就是不确定. 代码: /**************************************************** * author:xiefubao *********************

寻找假银币

寻找假银币是一个非常有趣的智力题目,寻找假银币的大意如下: 现在有8枚银币,其中一枚是假币.但是,从外观和做工上无法分辨哪枚是真币哪枚是假币,只知道假币的重量要比真币稍轻.则要求仅用一个天平,如何以最少的步骤寻找到假银币? 1. 寻找假银币算法 可以采用递归分治的思想来求解这个问题,操作步骤如下: (1)首先为每个银币编号,然后可以将所有的银币等分为两份,放在天平的两边. (2)因为假银币的分量较轻,因此天平较轻的一侧中一定包含假银币. (3)再将较轻的一侧中的硬币等分为两份,重复上述做法. (

算法设计与分析 ------最近对问题与8枚硬币问题

利用减治法实现8枚硬币问题: 参考资料:http://blog.csdn.net/wwj_748/article/details/8863503    算法设计--八枚硬币问题 1 #include "stdafx.h" 2 #include <iostream> 3 #include <stdio.h> 4 using namespace std; 5 6 7 void eightcoin(int arr[]); 8 void compare(int a,in

Exercise(13):八枚硬币

/* 八枚银币 在八枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重.可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测出这枚假币. 检测出假硬币所在位置以及该硬币是轻还是重 输入: 第一行输入八枚硬币的重量,分别用空格隔开 输出: 第二行输出假币在这八枚硬币中的位置 第三行输出假币偏重or偏轻 样例输入: 6 6 6 6 6 9 6 6 6 6 样例输出: 6 heavier 问题分析: 八枚硬币(a,b,c,d,e,f,g,h) 因

poj 1029 false coin

题目大意:就是一堆硬币中有一个假硬币,然后再给你几个天平的状态求出是否能找出哪个是假硬币并打印出编号. 主要思路: 可以使用穷举法.穷举1--n个硬币,分别判断是否是有问题的硬币(即假设该硬币有问题,是否与已知的天平判断结果一致),当然试探要分两种情况:重量轻了.重量重了.若全部试探完后发现:若个数为1,则说明有问题的硬币就是该硬币:否则说明有问题的硬币可能超过2个,则说明不能判断到底硬币是哪个. 主题思路清晰后,接下来就是如何判定是否与天平测试结果相一致.其实非常简单: 1)若为轻的情况. 1

最大熵模型简记

最近两天简单看了下最大熵模型,特此做简单笔记,后续继续补充.最大熵模型是自然语言处理(NLP, nature language processing)被广泛运用,比如文本分类等.主要从分为三个方面,一:熵的数学定义:二:熵数学形式化定义的来源:三:最大熵模型. 注意:这里的熵都是指信息熵. 一:熵的数学定义: 下面分别给出熵.联合熵.条件熵.相对熵.互信息的定义. 熵:如果一个随机变量X的可能取值为X = {x1, x2,-, xk},其概率分布为P(X = xi) = pi(i= 1,2, .

Counterfeit Dollar

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16424 题意 : 有12个硬币 有一个是假的 比其他的或轻或重     分别标记为A到L 然后输入cas 有个cas组数据 每组输入3行 每行3个字符串 第一个表示当时天平上左边有哪几个字符  第二个是右边 2边个数一样 但是不一定有几个 之后第三个字符串描述左边是比右边大小还是相等 问你  哪一个硬币是假的  假的相对于真的是清还是重  (假硬币有轻有重,只有一枚是

《程序员的数学思维修炼》 读书笔记

电子书定价:     ¥ 45.00       这是什么?                     纸书定价:     ¥ 45.00       Kindle电子书价格:     ¥ 1.99                   为您节省:     ¥ 43.01      (0.4折)            ~ 周颖   等 (作者) 发售日期: 2014年4月1日 本书是一本专门为程序员而写的数学书,介绍了程序设计中常用的数学知识.本书门槛不高,不需要读者精通很多高深的数学知识,只需要读