有12枚硬币,其中一枚与其他11枚不同,利用1架天平,如何只称3次就找出假币?

有12枚硬币,其中一枚与其他11枚不同,利用1架天平,如何只称3次就找出假币?,第1张

假币的重量与真的不一样

能利用天平称量三次,找出假币,并判断假币的重量比真币的重量重还是轻.

硬币分成三组,每组四枚,分别表示为:

G1 = (1,2,3,4),G2 = (5,6,7,8),G3 = (9,10,11,12).

在第一次称量时比较G1和G2,它们或者平衡或者一组更重些,下面分别考虑这两种情况:

如果G1和G2平衡,那么假币必定在G3中,即G1和G2中的所有硬币都是真的.这样,在第二次称量中,就可以比较任意三枚真币(比如1,2和3)和G3中的三枚硬币:

(1,2,3)和(9,10,11)

所得结果比较为:

1,、硬币平衡.这表明假币为12,因为它是G3中唯一在第二次称量中未出现的硬币,再进行第三次称量(比如1与12)就可以确知假币比其他硬币重还是轻.

2、硬币不平衡.这表明假币是9、 10、 11中的某一个,并且还可以知道假币是轻些还是重些.如果(1、 2、 3)比(9、 10、 11)重些,那么假币就轻些,反之亦然.再进行第三次称量(比如9与10)就可以确定是哪一枚是赝品.如果9和10平衡,那么假币是11,如果不平衡,那么根据前面已知的假币是轻些还是重些的信息就可以知道它们中的哪一枚是假币.

如果G1和G2不平衡,那么我们可以知道,1.、 假币在G1或G2中 2.、 硬币9.、 10、 11和12是真币.

把G2中的一枚硬币(比如5)移到天平的左边,在天平的右边加一枚真币(比如12).这样第二次称量就是(1、 2和5)与(3、 4、 12).

假设在第一次称量中,硬币(1、 2、 3、 4)比(5、 6、 7、 8)重些,那么在第二次称量中有三种可能的结果:

1、 硬币(1、 2、 5)重些.这表明硬币3、 4 和5是真的,因为我们改变了它们在天平中的位置,但称量的结果仍然不变(即左边重些).由于硬币12是真的,那么假币就是1或2,并且假币重些.再进行第三次称量(1与2)就可以马上确定哪枚是假币.

2、 硬币(3、 4、 5)重些.由于两车称量的结果发生了改变(也就是第一次称量天平左边重些,而现在右边重些),那么假币一定是从天平的一端移到了另一端.因此,或者硬币3或4是假的,并且重些.或者硬币5是假的,且轻些.这样再进行第三次称量(3与4)就可以确定出赝品.如果平衡,则假币是5,否则,较重的那个是假币.

3、 硬币(1、 2、 5)和(3、 4、 12)平衡.这表明假币必定不包含在第二次称量中,而必为6、 7或8中的一枚.同时,从第一次称量的结果可知假币较轻.这样,再进行第三次比较。

扩展资料:

c语言题目 - 称硬币

描述  

赛利有12枚银币。其中有11枚真币和1枚假币。假币看起来和真币没有区别,但是重量不同。但赛利不知道假币比真币轻还是重。于是他向朋友借了一架天平。朋友希望赛利称三次就能找出假币并且确定假币是轻是重。例如:如果赛利用天平称两枚硬币,发现天平平衡,说明两枚都是真的。如果赛利用一枚真币与另一枚银币比较,发现它比真币轻或重,说明它是假币。经过精心安排每次的称量,赛利保证在称三次后确定假币。

关于输入  

第一行是n,表示数据共有n组。  

其后是n*3行。每组数据有三行,每行表示一次称量的结果。赛利事先将银币标号为A-L。每次称量的结果用三个以空格隔开的字符串表示:天平左边放置的硬币 天平右边放置的银币 平衡状态。其中平衡状态用"up", "down", 或 "even"表示, 分别为右端高、右端低和平衡。天平左右的银币数总是相等的。

关于输出  

输出为n行。每行输出一组数据中哪一个标号的银币是假币,并说明它比真币轻还是重。  

如果第K枚银币是假,并且它是轻的,则输出:  

K is the counterfeit coin and it is light.  

如果第K枚银币是假,并且它是重的,则输出:  

K is the counterfeit coin and it is heavy.

例子输入  

1

ABCD EFGH even

ABCI EFJK up

ABIJ EFGH even

例子输出  

K is the counterfeit coin and it is light.

#include<stdio.h>

int findCoin(int coin[],int front,int back) ——coin[]是质量,front是第一个,back是最后一个(按照0——29编号)

{

int i,sumf=0,sumb=0,sum=0

if(front+1==back)

{

if(coin[front]<coin[back])

return front+1

else return back+1

}

if((back-front+1)%2==0) ——分为两组,每组(back-front)/2个(剩余偶数个)

{

for(i=fronti<=front+(back-front)/2i++)

sumf=sumf+coin[i]——sumf是前一组(back-front)/2总质量

for(i=front+(back-front)/2+1i<=backi++)

sumb=sumb+coin[i]——sumb是后一组(back-front)/2总质量

if(sumf<sumb)

return findCoin(coin,front,front+(back-front)/2)

if(sumf>sumb)

return findCoin(coin,front+(back-front)/2+1,back)

} ——两组质量比较,返回质量小的一组

if((back-front+1)%2!=0) ——分为两组,每组(back-front)/2个余1个(剩余奇数个)

{

for(i=fronti<=front+(back-front)/2-1i++)

sumf=sumf+coin[i]——sumf是前一组(back-front)/2个总质量

for(i=front+(back-front)/2+1i<=backi++)

sumb=sumb+coin[i] ——sumb是后一组(back-front)/2个总质量

sum=coin[front+(back-front)/2]——sum是剩余的一个金币质量

if(sumf<sumb)

return findCoin(coin,front,front+(back-front)/2-1)

if(sumf>sumb) ——两组质量比较,返回质量小的一组

return findCoin(coin,front+(back-front)/2+1,back)

if(sumf+sum==sumb+sum) ——直到两组质量相同,剩余的一个为假币,返回编号

return front+(back-front)/2+1

}}

int main()

{

int coin[30]={1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}

printf("那个假币是第%d个金币!\n",findCoin(coin,0,29))

system("PAUSE")

return 0}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8140869.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-13
下一篇 2023-04-13

发表评论

登录后才能评论

评论列表(0条)

保存