zoukankan      html  css  js  c++  java
  • 【三分】【AOJ-158】有假币

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

    Input
    1≤n≤2^30,输入0结束程序。
    Output
    最少要称几次一定能把那个假币找出来。
    Sample Input
    3
    12
    0

     
    Sample Output
    1
    3
     
     
    思路:
    三分法

    一、     首先我们先来考虑最简单的问题1。为了方便叙述,把n个硬币按1,2,…,n顺次编号。

    二、     若n=3,把一号硬币放在天平左边、二号硬币放在天平右边。如果天平:

    三、     左偏,一号重,是假币。

    四、     右偏,二号重,是假币。

    五、     保持平衡,那么一、二都是正常的硬币,因此就只有可能三号硬币是假币了。

    六、     因此n=3,至多一次就能称出哪个是假币。记作f(3)=1。

    七、     下面考虑n=9。把所有的硬币分成三组:A{1,2,3},B{4,5,6},C{7,8,9}。A组的硬币放在左边、B组放在右边。如果天平:

    八、     左偏,则假币在A组里面。

    九、     右偏,则假币在B组里面。

    十、     保持平衡,假币在C组里面。

    十一、   无论在哪个组里面,我们已经把假币的范围从“9”缩小到了“3”,也就是减少到原来的1/3。之前我们已经研究过,3个硬币1次就能称出来,故而f(9)=2。

    十二、   不难推广到一般的情况:

    十三、   定理1.1 f(3n)=n。

    十四、   证明:n=1,2时,已证。设n=k成立,则f(3k)=k;下面考虑n=k+1的情况。

    十五、   将3k+1个硬币分成三堆A, B, C,使得|A|=|B|=|C|=3k。把A放在天平左边、B放在右边,天平:

    十六、   左偏,假币在A

    十七、   右偏,假币在B

    十八、   平衡,假币在C

    十九、   无论哪种结果,我们都把假币的范围缩小到了3k个硬币里面。而f(3k)=k,故而f(3k+1)=k+1。

    二十、   综上,定理1.1成立。

    二十一、稍经分析不难得到:

    二十二、定理1.2 f(n)=

    二十三、这个的证明和定理1.1完全类似,分n mod 3 = 0, 1, 2适当讨论即可。

    二十四、我们必须注意到 是可行的,因为我们能够构造出这样一个方案。问题是它是否最优?

    二十五、我们采取的方案是每次将硬币尽量均匀的三分,这样做的根据就是天平只有三种结果:左偏、右偏、平衡。于是就能保证无论假币在哪一份都能将结果的范围缩小到原来的1/3。从感性上认识, 应该就是最优解了。

    二十六、为了更加严格的证明 的最优性,我们引进判定树的概念。

    二十七、下图就是n=9时的一种判定树:

    二十八、此题的判定树是这样一棵树:

    二十九、叶子节点代表一种可能的结果。

    三十、   非叶子节点代表一次称量。

    三十一、非叶子节点至多有三个儿子,分别代表天平的左偏、右偏、平衡三种情况。

    三十二、任意一种称量方案都能唯一的表示成一棵判定树;反过来一棵判定树也唯一对应一种称量方案。

    三十三、容易看出判定树的深度就是称量次数。这就是我们之所以引进它的原因。

    三十四、做出判断之前,谁也无法预知哪个硬币是假币,每个都有可能是我们的目标;因此一个有意义的判定树应该具有至少n个叶子节点。

    三十五、 n个叶子节点的树的深度h ≥ ,故而可以证明,f(n)= 是最优的。

    三十六、 我们的结论是:有n(n≥3)个硬币,其中一个是假币,假币的重量比其他的要重一些。给一架天平,至少称 次,就能找出那个假币。

    三十七、 具体的方案是将硬币每次都尽量均匀的三分。

    三十八、 让我们总结一下。

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

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

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

     

     

    参考代码

    #include <stdio.h>
    #include <math.h>
    int main()
    {
        long int n;
        int m;
        while(scanf("%ld",&n)&&n)
        {
            m=(int)ceil(log(n*1.0)/log(3.0));//ceil()向上取整函数 log(n)/log(3)用三分法可证
            printf("%d
    ",m);
        }
        return 0;
    }
  • 相关阅读:
    修复 Visual Studio Error “No exports were found that match the constraint”
    RabbitMQ Config
    Entity Framework Extended Library
    Navisworks API 简单二次开发 (自定义工具条)
    NavisWorks Api 简单使用与Gantt
    SQL SERVER 竖表变成横表
    SQL SERVER 多数据导入
    Devexpress GridControl.Export
    mongo DB for C#
    Devexress XPO xpPageSelector 使用
  • 原文地址:https://www.cnblogs.com/ahu-shu/p/3471779.html
Copyright © 2011-2022 走看看