一个有趣的天平秤球问题

最近在网上看到一个题目,题设简单明了,本以为解决起来相当简单,细想之下却是有一定难度。这个题的题意如下: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为目标球,且较重(轻);如果不等重,则较重(轻)者为目标球。

时间: 2024-10-07 03:20:36

一个有趣的天平秤球问题的相关文章

关于java除法的一个有趣例子。

今天逛贴吧的时候偶然发现吧友的一个有趣例子. public class Demo{     public static void main(String[]args){         System.out.println(24/0);  //会抛byzero异常         System.out.println(24.0/0.0) //可以输出,输出为Infinity:     } } 目前对于第二句为什么不会报byzero异常也不知道.先做个标记.理解了再补充上.

一个有趣的SQL Server 层级汇总数据问题

看SQL Server大V宋大侠的博客文章,发现了一个有趣的sql server层级汇总数据问题. 具体的问题如下: parent_id emp_id emp_name total_amout     NULL 2 Andrew 200     2 1 Nancy 100     2 3 Janet 120     3 4 Michael 80     1 5 Robert 50     每个员工的总销售额=自己的销售额+其下级员工的总销售额,     比如:     Andrew = 200_

一个有趣的Timer应用

import java.util.Date; import java.util.Timer; import java.util.TimerTask; public class TraditionalTimerTest { static int count; public static void main(String[] args) { class MyTimerTask extends TimerTask { @Override public void run() { count = (cou

一个有趣的现象(苹果的bug Or 坑?),关于区分真机和模拟器的预编译宏

TARGET_IPHONE_SIMULATOR和TARGET_OS_IPHONE 是苹果的两个宏定义, 在真机sdk中位于ios->usr/include/targetconditionals.h中, 在模拟器sdk中位于simulator->usr/include/targetconditionals.h中 (笔者此时使用的xcode版本为5.1,sdk版本是7.1) 仔细看其模拟器sdk中的定义: #define TARGET_OS_IPHONE            1 #define

Nim Game,一个有趣的游戏,也是一道入门算法题。

Nim Game,其实很多人都玩过.其实就是我们玩的划线游戏. 一张纸上,画若干条线,双方一人划一次,每次划掉1~3条线.可以选择画1条,也可以划2条,也可以3条.具体划去几条线完全看自己的策略.谁划掉最后一条线,就是赢家. 如上图,蓝方获胜. 正在看这篇文章的你一定是一个聪明人,每一步都是最优解,而你的对手,也跟你一样聪明,每步都是最优的解法. 现在你作为先手,在线条总数为多少的时候,你必赢呢,又在多少的时候必输呢? 可不可以用一个函数来判断在线条总是为x时你的输赢情况呢?这样你以后跟别人玩这

转:做一个有趣的有意思的人

(本文转自 现代简明魔法 在此特别表示感谢) 今天吃午饭时,听到隔壁说菜上面有虫的事,突然想起了去年离职的技术总监林工.那就水点破事,写个小短篇吧. 如果是林工的话,他肯定会说,幸好是发现一条虫,而不是半条.脑补了一下,然后自己就乐呵乐呵了.他是个很有趣的人,很有意思的人,首先没啥领导架子,然后很关怀人,说话很风趣,平时就捣鼓一些在一般人眼里觉得奇怪的东西,比如树莓派,模型,自己设计组装亚克力架什么的.新年红包总是有惊喜,比如是一张老毛子再加一张10元葡币什么的(我们珠海这里很近澳门)--反正跟

当filter使用函数而非选择器来过滤元素时的一个有趣的地方

JQuery官方API关于filter方法的介绍有这么一个实例: <div id="first"></div> <div id="second"></div> <div id="third"></div> <div id="fourth"></div> <div id="fifth"></div

一个有趣的回答(摘自http://www.51testing.com/html/03/n-860703.html)

假设这有一个各种字母组成的字符串,假设这还有另外一个字符串,而且这个字符串里的字母数相对少一些.从算法上讲,什么方法能最快的查出所有小字符串里的字母在大字符串里都有? 比如,如果是下面两个字符串: String 1: ABCDEFGHLMNOPQRS String 2: DCGSRQPOM 如果这样呢--假设我们有一个一定个数的字母组成字串--我给每个字母分配一个素数,从2开始,往后类推.这样A将会是2,B将会是3,C将会是5,等等.现在我遍历第一个字串,把每个字母代表的素数相乘.你最终会得到一

一个有趣的 SQL 查询(查询7天连续登陆)

一个有趣的 SQL 查询 一个朋友有这样一个SQL查询需求: 有一个登录表(tmp_test),包含用户ID(uid)和登录时间(login_time).表结构如下: *************************** 1. row *************************** Field: uid Type: int(10) unsigned Null: NO Key: MUL Default: NULL Extra: *************************** 2.