Exercise(13):八枚硬币

/*
        八枚银币
    在八枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是较重。可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测出这枚假币。

    检测出假硬币所在位置以及该硬币是轻还是重        

    输入:
    第一行输入八枚硬币的重量,分别用空格隔开
    输出:
    第二行输出假币在这八枚硬币中的位置
    第三行输出假币偏重or偏轻

    样例输入:
    6 6 6 6 6 9 6 6 6 6
    样例输出:
    6
    heavier

    问题分析:
        八枚硬币(a,b,c,d,e,f,g,h)
        因为八枚硬币中 有1枚硬币与其他7枚不同。
        故可将八枚分为三组:
        1、 a,b,c
        2、 d,e,f
        3、 g,h
        过程( 可以通过一架天平来任意比较两组硬币 );
        i、判断(a,b,c)与(d,e,f)的重量
            (1) (a,b,c) == (d,e,f)  * 即假币必定为 g or h *
                先判断if( g > h ),再判断g(or h)是否等于(a,b,c,d,e,f)中的一个:
                                    若是 则h(or g)为假币,并输出结果 lighter.
                                    若否 则h(or g)为假币,并输出结果 heavier.

            (2) (a,b,c) > (d,e,f)   * 即假币必定为 a or b or c or d or e or f *
                重新分组为 (a,e) (b,d) (c,f): 交换 b,e 的位置可判断出 (a,d) 为假 or (b,e)为假.
                判断if( a+e > d+b ) 符号仍为 > :说明 假币必为(a,d)中的一枚
                    if( a+e == d+b )            说明 假币必为(c,f)中的一枚
                    if( a+e < d+b ) 符号改变 :  说明 假币必为(b,e)中的一枚 

            (3) (a,b,c) < (d,e,f)   * 即假币必定为 a or b or c or d or e or f *
                判断if( a+e < d+b ) 符号仍为 < :说明 假币必为(a,d)中的一枚
                    if( a+e == d+b )            说明 假币必为(c,f)中的一枚
                    if( a+e > d+b ) 符号改变 :  说明 假币必为(b,e)中的一枚    

        ii、由此,声明3个函数分别处理
            ①EightCoins 用于区分可能的假币组(elem1,elem2)
            ②Compare    用于区分出假币(sham)
            ③Print      用于打印结果
        iii、代码实现如下...

*/
#include <iostream>
using namespace std;

void EightCoins(int* arr);                                          // 判断真假
void Print(int sham,int real,int index);                            // 输出
void Compare(int elem1,int elem2,int real,int index1,int index2);   // 判断轻重 

int main()
{
    int i;
    int arr[8];

    for( i=0; i<8; i++ )
        cin>>arr[i];

    EightCoins(arr);

    return 0;
}

// 判断轻重
void EightCoins(int* arr)
{
    int a = arr[0],
        b = arr[1],
        c = arr[2],
        d = arr[3],
        e = arr[4],
        f = arr[5],
        g = arr[6],
        h = arr[7];
    int abc = a+b+c,
        def = d+e+f;

    if(abc > def)
    {
        if( (a+e) > (d+b) )         // 去除c,f 并 互换b,e的位置 仍然 >    说明a,d中必有一枚为假币
            Compare(a,d,g,0,3);
        else if( (a+e) == (d+b) )   // 去除c,f    (a+b) == (d+e)          说明c,f中必有一枚为假币
            Compare(c,f,g,2,5);
        else                        // 去除c,f 并 互换b,e的位置 符号改变  说明b,e中必有一枚假币
            Compare(b,e,g,1,4);
    }
    else if(abc == def)
            Compare(g,h,a,6,7); // 最好的情况
    else
    {
        if( (a+e) < (d+b) )         // 去除c,f 并 互换b,e的位置 仍然 >    说明a,d中必有一枚为假币
            Compare(a,d,g,0,3);
        else if( (a+e) == (d+b) )   // 去除c,f    (a+b) == (d+e)          说明c,f中必有一枚为假币
            Compare(c,f,g,2,5);
        else                        // 去除c,f 并 互换b,e的位置 符号改变  说明b,e中必有一枚假币
            Compare(b,e,g,1,4);
    }
}

// 比较真假
void Compare(int elem1,int elem2,int real,int index1,int index2)
{
    if(elem1 == real)
        Print(elem2,real,index2);
    else
        Print(elem1,real,index1);
}

// 输出
void Print(int sham,int real,int index)
{
    if(sham > real)
        cout<<index+1<<endl<<"heavier"<<endl;
    else
        cout<<index+1<<endl<<"lighter"<<endl;
}
时间: 2024-08-01 21:24:48

Exercise(13):八枚硬币的相关文章

[经典算法] 八枚硬币

题目说明: 现有八枚银币a b c d e f g h,已知其中一枚是假币,其重量不同于真币,但不知是较轻或较重,如何使用天平以最少的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重. 题目解析: 单就求假币的问题是不难,但问题限制使用最少的比较次数,所以我们不能以单纯的回圈比较来求解,我们可以使用决策树(decision tree),使用分析与树状图来协助求解.一个简单的状况是这样的,我们比较a+b+c与d+e+f ,如果相等,则假币必是g或h,我们先比较g或h哪个较重,如果g较重,再与

八枚硬币

理论: 现有八枚银币a b c d e f g h,已知其中一枚是假币,其重量不同於真币,但不知是较轻或较重,如何使用天平以最少的比较次数,决定出哪枚是假币,并得知假币比真币较轻或较重 解法 单就求假币的问题是不难,但问题限制使用最少的比较次数,所以我们不能以单纯的迴圈比较来求解,我们可以使用决策树(decision tree),使用分析与树状图来协助求解. 一个简单的状况是这样的,我们比较a+b+c与d+e+f ,如果相等,则假币必是g或h,我们先比较g或h哪个较重,如果g较重,再与a比较(a

C - The C Answer (2nd Edition) - Exercise 1-3

/* Modify the temperature conversion program to print a heading above the table. */ #include <stdio.h> /* print fahrenheit-Celsius table for fahr = 0, 20, ..., 300; floating-point version */ main() { float fahr, celsius; int lower, upper, step; lowe

Exercise 13: Parameters, Unpacking, Variables

from sys import argv script, first, second, third = argv print "The script is called:", scriptprint "Your first variable is:", firstprint "Your second variable is:", secondprint "Your third variable is:", third Resu

算法设计与分析 ------最近对问题与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

The C Programming Language——Exercise solutions of the chapter one (1st)

Recently,I have been reading the book The C Progrmming Lanuage(2nd Edition),which written by Dennis M.Ritchie and Brian W.Kernighan.The are many useful and elegant exercises in the book.Here is my solutions to the exercises of the first chapter but n

Ex 6_17 数量无限的硬币兑换问题_第七次作业

子问题定义:定义一个数组b,大小比兑换价格的大小多一个元素,其中b[i]表示是否能用面值为x1,x2,x3,..,xn的硬币兑换价格i. 递归关系: 初值设定:设b[0]=true 求解顺序:按下标从小到大依次求解b[i]的值,最后返回b[v]中的结果即为最终结果. 1 package org.xiu68.ch06.ex7; 2 3 public class Ex6_17 { 4 5 //数量无限的面值为x1,x2,x3,...,xn的硬币是否能兑换价格v 6 public static voi

第 13 章

13.1 [出题思路] 理解拷贝构造函数的基本概念. [解答] 如果构造函数的第一个参数是自身类类型的引用,且所有其他参数(如果有的话)都有默认值,则此构造函数是拷贝构造函数.拷贝构造函数在以下几种情况下会被使用: 拷贝初始化(用 = 定义变量). 将一个对象作为实参传递给非引用类型的形参. 一个返回类型为非引用类型的函数返回一个对象. 用花括号列表初始化一个数组中的元素或一个聚合类中的成员. 初始化标准库容器或调用其 insert/push 操作时,容器会对其元素进行拷贝初始化. 13.2 [

完全数

程序地址:http://www.cheemoedu.com/exercise/13 问题描述: 完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数.它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身.例如,第一个完全数是6,它有约数1.2.3.6,除去它本身6外,其余3个数相加,1+2+3=6.第二个完全数是28,它有约数1.2.4.7.14.28,除去它本身28外,其余5个数相加,1+2+4+7+14=28.编程求10000以内的完全数. 我的