假币问题

Posted edviv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了假币问题相关的知识,希望对你有一定的参考价值。

 

Description:

居然有假币!!! 事情是这样的,现在猪肉涨了,但是农民的工资却不见涨啊,没钱怎么买猪肉啊。老王这就去买猪肉,结果找来的零钱中有假币!!!可惜老王一不小心把它混进了一堆真币里面去了。现在知道假币的重量比真币的质量要轻。给你一个天平,请用最快的时间把那个可恶的假币找出来。

Input:

输入有多行,每一行的值为硬币的数目n,1≤n≤2^30,输入0结束程序

Output:

最少要称多少次一定能把那个假币找出来。输出对应输入行数。

Sample Input Copy:

3

12

0

Sample Output Copy:

1

3

HINT

示例1中共有3枚硬币,所以任意取2个放天平上称量一下。 因为假币的重量比较轻。 如果天平不平衡,则较轻的那枚就是假币。 如果天平平衡,则说明这两枚硬币都是真的,而剩下那枚是假币。

题解:假设我们现在只有三枚硬币,那么我们分成三分A , B, C

1.若 A == B  ,则 C 是假币

2.若 A < B    ,  则 A 是假币

3.若A > B     ,  则 B 是假币

则推出一个结论: f(3) = 1   --- >  继续推广  f( 9 ) = ?

现在分成 3A, 3B, 3C 三部分

1.若 3A == 3B ,则在 3C中查找,现在继续把 3C 分成 3 部分 AA, BB , CC 三部分

(1).若 AA == BB ,则 CC 是假币 

(2).若 AA <  BB  ,  则 AA  是假币 

(3).若 AA >  BB  ,  则 BB  是假币

2.若 3A >   3B  , 则假币在 3B 中查找, 现在继续把 3B  分成 3 部分 AA, BB , CC 三部分

(1).若 AA == BB ,则 CC 是假币 

(2).若 AA <  BB  ,  则 AA  是假币 

(3).若 AA >  BB  ,  则 BB  是假币

3.若 3A <   3B , 则假币在 3A 中查找, 现在继续把 3A 分成三部分 AA, BB, CC 三部分

1).若 AA == BB ,则 CC 是假币 

(2).若 AA <  BB  ,  则 AA  是假币 

(3).若 AA >  BB  ,  则 BB  是假币

推出一个结论:f(9) = 2  ----- >  那么我们得出一个结论 f(3^n) = n, f(3^n + 1) = n + 1

最后我们得出一个结论:我们的结论是:有n(n≥3次,就能找出那个假币。)个硬币,其中一个是假币,假币的重量比其他的要重一些。给一架天平,至少称技术图片次,就能找出那个假币。

分析过程可以画成一棵树,叶子节点顶多只访问一次,然后逐步向下搜索。

“三分”是整个解法的核心。我们选择三分,而不是二分或者四分是有原因的,它的本质是由判定树的特殊结构——三叉树——所决定的。

同时还必须注意一点,我们在三分的时候有两个字很讲究:“均匀”。实际上树的深度 ≥ 中的“=”当且仅当硬币被均匀的分配时才能达到。

这里说的“均匀”是指“在最坏情况下获得最好的效果”。因为一棵树的深度是由它根节点儿子中深度最大的儿子决定的,为了使得整个树深度最小,我们就要务必使得深度最大的儿子深度最小,这就是“均匀”分配的理论根据。

 

 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 int main()
 7 
 8     int n;
 9     while(~scanf("%d",&n))
10     
11         if(n == 0) break;
12         if(n == 1)
13         
14             cout<<"0"<<endl;
15             continue;
16         
17         int count = 0, flag = 0;
18         while(n)
19         
20             if(n%3 && n!= 1)
21                 flag++;
22             n /= 3;
23             count++;
24         
25         if(flag == 0)
26             count--;
27         cout<<count<<endl;
28     
29     return 0;
30 

 

以上是关于假币问题的主要内容,如果未能解决你的问题,请参考以下文章

假币问题

假币问题

如何在假币算法中称重

分治算法在 O(logn) 中找到假币

12枚硬币,怎么3次称出假币

算法设计--八枚硬币问题