zoukankan      html  css  js  c++  java
  • 一个有趣的天平秤球问题

    最近在网上看到一个题目,题设简单明了,本以为解决起来相当简单,细想之下却是有一定难度。这个题的题意如下:12个外观一致的球,其中只有一个重量不同,要求使用天平称重3次即找出这个不同重量的球并判断其较重还是较轻。

        继续阅读下文之前建议大家先尝试思考一下解决方案。

        读者朋友可能在尝试了几种方案之后仍然无法解决,当然有条件的话大家可以通过实物去试验每一次称重,比较直观。下面我提供一个计算机的小程序(C语言编写)来模拟题目中的天平称重,其实也可以当成是一个趣味小游戏来玩玩。​ 

    #include <stdio.h>
    
    #include <stdlib.h>
    
    int main(int argc, const char * argv[]) {
    
        int num[13] = {0,5,5,5,5,5,5,5,5,5,5,5,5};
    
        int test = arc4random_uniform(12) + 1;
    
        int value = arc4random_uniform(2);
    
        if (value == 0){num[test] = 4;}else {num[test] = 6;}
    
        int a ,b ,c ,d ,e ,f,g ,h ,i ,j ,k ,l ;  
    
        for (int I = 0; I < 4;I++) {
    
    printf("请输入天平左边的球(编号1~12):");
    
    a = 0,b = 0,c = 0,d = 0,e = 0,f = 0,g = 0,h = 0,i = 0,j =0,k = 0,l = 0; 
    
    scanf("%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i%i,i",&a,&b,&c,&d,&e,&f,&g,&h,&i,&j,&k,&l);
    
         int sum = num[a] + num[b] + num[c] + num[d] +num[e] + num[f] + num[g] + num[h] + num[i] + num[j] + num[k] + num[l];
    
        printf ("请输入天平右边的球(编号1~12):");rewind(stdin);
    
    a = 0,b = 0,c = 0,d = 0,e = 0,f = 0,g = 0,h = 0,i = 0,j =0,k = 0,l = 0;     scanf("%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i",&a,&b,&c,&d,&e,&f,&g,&h,&i,&j,&k,&l);
    
        int sum1 = num[a] + num[b] + num[c] + num[d] +num[e] + num[f] + num[g] + num[h] + num[i] + num[j] + num[k] + num[l];
    
        if (sum > sum1)    { printf("天平向左倾斜");}
    
        else if(sum < sum1){ printf("天平向右倾斜");}
    
        else{ printf ("天平平衡");}
    
        printf ("您找到那个球了吗,请输入编号,否则输入0继续操作:");
    
        rewind(stdin);    
    
        scanf("%i",&a);
    
        if (a == test) {  printf ("恭喜您,您已经找到那个球,请输入0或1,0代表此球较轻,1代表此球较重");
    
         scanf("%i",&b); 
    
        if( ((b == 0)&&(num[test] == 4)) || ((b == 1)&&(num[test] == 6))) { printf ("恭喜您,答对了");}else  printf ("答错了");break; }
    
        else if (a == 0); 
    
        else   printf ("抱歉,您没找到那个球%i",test);    }
    
        return 0;}

    那么笔者是如何思考这个问题的呢?其实很简单,就是有顺序的尝试每种可能。第一步有多少种可能,第二步有多少种可能。。。

    第一次称重,笔者认为天平两侧各取3个或4个更有可能找到解决方案(中间值使得确定或不确定的球都在较合理的范围内)。天平两侧各取3个,你很快会发现如果天平平衡,3次称重将无法保证找到目标球;​天平两侧各取4个,如果天平平衡,那么很简单,3次称重可以找到目标球,如果不平衡,考虑起来就相对费劲,同样,此时笔者认为第二次称重各取3个或4个更有可能找到解决方案,笔者刚开始是选择天平两侧各取4个的策略,这时可以确定的是哪4个球是等重量的。试考虑天平的一侧从第一次称重时8个未确定的球中取4个,即取第一次称重时较重的4个球中的x个及较轻的4个当中的4-x个(x为0至4的整数),另一侧放置已确定等重的4个球。现举例说明x为2的情况,其实等效于交换了第一次称重时两边的两个球,如果此时称重跟第一次称重时天平倾向有变,则说明交换的4个球中必有一个是目标球。如果你有认真思考,你会发现,第二次称重时天平两侧各4个球且其中含4个已确认等重球的情况下,任何球的组合都是无法在题设所要求的3次称重内找到目标球的(这个结论读者朋友可以试着证明)。​​得出这个结论,笔者当时是几近崩溃的,其实在这个结论的思考过程中也有助于通过逆向思维的方式修正方案:思考怎样的条件下才能导致特定的一个结果。

    。。。。。。

    最后附上参考答案(游戏攻略):

    步骤1、  第一次称重,任取8个球比较,

    (1.1)不等重,此时标记 1234> abcd(为描述方便,此式表示编号1234球的总重大于编号abcd球的总重,下文类似),其余4个球编号为5678 

    (1.2)等重,标记为1234 = abcd,其余4个球编号为5678。

    步骤2、(1.1)情况下:1234中取出3个,abcd中取出2个,分放天平左右两侧,再两边交换一个球,最后选5678的一个球放入天平右边。

    比如选取  12a 与 3b5分放天平两侧,进行第二次称重。

           (1.2)情况下:可取567 与abc 进行第二次称重。

    步骤3、(1.1)情况下:

    第三次称重,如果上一步 12a = 3b5,则说明,目标球在 4 或 cd中。称重c与d。如果等重,则较重者4为目标球;否则较轻者为目标球。

    如果上一步 12a > 3b5,则说明:目标球在 12 或 3 中,称重1与2,如等重,则较轻者3为目标球;否则较重者为目标球。

    如果上一步 12a < 3b5,则说明:目标球在 a 或 3 中,称重1与a,如等重,则为3,且较重。

    (1.2)情况下:如果上次称重567较重(轻),取5与6进行第三次称重。如等重,则7为目标球,且较重(轻);如果不等重,则较重(轻)者为目标球。

  • 相关阅读:
    编程语言的发展趋势及未来方向 目录 编程语言的发展趋势及未来方向 1 第一章 一、历史回顾及趋势概述 2 第一节 首先,编程语言的发展非常缓慢。oo等等,但是远没有好上1000倍。 3 第二节 出现
    Atitit datatype 数据类型 目录 第一章 三大基本类型 数字 字符串 bool 1 第二章 基本类型vs引用类型 1 字符串类型 2 第三章 符合类型vs 简单类型 2 特殊类型
    Atitit 乔姆斯基分类 语言的分类 目录 1.1. 0 –递归可枚举语法 1 1.2. 1 –上下文相关的语法 自然语言 1 1.3. 2 –上下文无关的语法 gpl编程语言 1 1.4. 3
    桁架系统控制
    Pset_RoofCommon
    Pset_ShadingDeviceCommon
    Pset_SlabCommon
    gis数据下载地址
    Pset_StairCommon
    Pset_StairFlightCommon
  • 原文地址:https://www.cnblogs.com/imsz/p/5561102.html
Copyright © 2011-2022 走看看