zoukankan      html  css  js  c++  java
  • 砝码称重2

    参考

    https://blog.csdn.net/livelylittlefish/article/details/3854702

    https://www.guokr.com/article/3742

    http://yetanothermathprogrammingconsultant.blogspot.com/2016/03/the-weight-problem-of-bachet-de-meziriac.html

    http://www2.washjeff.edu/users/mwoltermann/Dorrie/2.pdf

    https://brilliant.org/discussions/thread/the-weight-problem-of-bachet-de-meziriac/

    http://josmfs.net/wordpress/wp-content/uploads/2019/04/Weight-Problem-of-Bachet-190410.pdf

    https://www.cnblogs.com/ttltry-air/archive/2012/08/17/2644397.html

    问题:4个砝码,每个重量都是整数克,总重量为40克,放在天平上可以称出1~40克的物体。求这4个砝码各多少克。

    最简单的方法,穷举法,不过穷举法性能太低了,当前物品为x(x>0 x<=40),把砝码分成4个(abcd),a+b+c+d=40,n1*a+n2*b+n3*c+n4*d=x,再判断是否有n1*a+n2*b+n3*c+n4*d=(1-40),如果有,就满足。

    穷举法太麻烦了,不管是笔试还是正式工作中,都不可能用这个方法。那么有没有其他的方法呢?既然这样说了,肯定是有的。这是一道经典的数学问题-德·梅齐里亚克的法码问题(The Weight Problem of Bachet de Meziriac),也叫巴协 (Bachet) 砝码,原版描述如下

    一位商人有一个40磅的砝码,由于跌落在地而碎成4块.后来,称得每块碎片的重量都是整磅数,而且可以用这4块来称从1至40磅之间的任意整数磅的重物.
    问这4块砝码碎片各重多少?
    上面几篇引用说的比较好,不过呢,不是数学系的,证明就算了。我们直接用得出的结论。记住,这是天平两边都可以放置的结论,还有放置一边的有其他结论。
    结论一 ,n个不同的砝码,最大可以表示到(3^n-1)/2的连续正整数。比如这个题目非常巧妙的给定了4个砝码,那么就是3^4=81 81-1=80 80/2=40。也就1-40任意一个整数最少需要4个不同的砝码表示。
    结论二,给定最大重量m,使用最少的砝码称得1-m任意一种重量,求每个砝码是多少。因为是可以放天平两边,也可以不放,那么就有3种状态,那么就是3^0 3^1 3^2...3^n。所以如果是40,那么又(3^n-1)/2=40可以得出n=4,那么四个砝码就是[0, 4)3^n,就是1 3 9 27。
    这里还可以这一样理解,首先一个砝码都没有,那就是0,0不管放天平哪边,还是不放,都一样,只有一种状态,那么它只能跨度为1,所以0+1=1;到了1,因为可以天平两边都放,包括前面的0,所以有-1 0 1三种状态,那么跨度就是1-(-1)=2,所以下一个是3;到了3,3自己有-3 0 3,包含前面的1,那就是-4 0 4,跨度就是8,那么下一个就是9.
    还可以借用上面评论中的一条

    也就是一共n个砝码,每个3种状态,那么就是3*3*3...*3个排列组合,就是3^n,但是有一个0,大家都一样,所以就是3^n-1,但是由于我们不可能称重负数物品,也就是要把对称总和加起来是负数的去掉,也就是(3^n-1)/2

    如果是只能放到一边,那么需要的砝码就是2^n,1 2 4 6 8
    int main()
    {
        int num = 0;
        cin >> num;
        //(3^n-1)/2
        num = num * 2 + 1;
        int n = 0;
        while (num > 1)
        {
            num = num / 3;
            n++;
        }
        int fmweight = 0;
        for (int i = 0; i < n; i++)
        {
            if (i == 0)
            {
                fmweight = 1;
            }
            else
            {
                fmweight = fmweight * 3;
            }
            cout << fmweight << " ";
        }
        char inchar;
        cin >> inchar;
    }
  • 相关阅读:
    js用currentStyle和getComputedStyle获取css样式(非行间)
    XMLHttpRequest Level 2 使用指南
    image-set实现Retina屏幕下图片显示[转载]
    Png的秘密
    css清除&闭合浮动
    2016学习计划
    提高性能及操作硬件的能力
    新兵易学,老兵易用----C++(C++11的学习整理---如何减少代码量,加强代码的可读性)
    CV限制符--C++
    能ping通网络,也正常连接,就是打不开网页,无法访问网络
  • 原文地址:https://www.cnblogs.com/studywithallofyou/p/12103589.html
Copyright © 2011-2022 走看看