一个数学小魔术的证明

⑴ 让对方随便写一个五位数(五个数字不要都相同的)
⑵ 用这五位数的五个数字再随意组成另外一个五位数
⑶ 用这两个五位数相减(大数减小数)
⑷ 让对方想着得数中的任意一个数字,把得数的其他数字(除了对方想的那个)告诉你
⑸ 表演者只要把对方告诉你的那几个数字一直相加到一位数,然后用9减就可以知道对方想的是什么数了

例:五位数一:57429;五位数二:24957;相减得:32472;
心中记住:7;余下的告诉表演者:3242;
表演者:3+2+4+2=11;1+1=2;9-2=7(既对方心中记住的那个数了)

觉得挺有意思,然后就证明了一下。

小学时候说过,一个整数如果是9的倍数,当且仅当它的各位数的和也是9的倍数。稍微扩展一下,如果一个整数整除 9 的余数是r,当且仅当它的各位数的和整除 9 的余数是也是r。先证明一下。

必要性:
n = d1 + 10×d2 + 100×d3…… = Σ(10i×di)         (1)

9k + r = d1 + d2 + d3 …… = Σdi                         (2)
(1) – (2) 得
n – 9k – r = Σ((10i-1 – 1)×di),n = Σ((10i-1 – 1)×di) + 9k + r

∵ 10i – 1 = (10 – 1)(10i-2 + 10i-3 + 10i-4 + ….)
∴ n = 9×(Σ(10i-2×di) + k)  + r 即 n 整除 9 的余数是 r

充分性:
n = 9k + r = d1 + 10×d2 + 100×d3…… = Σ(10i×di)
9k + r = Σdi + Σ((10i-1 – 1)×di)
Σdi = 9k + Σ((10i-1 – 1)×di) + r = 9k + 9×Σ(10i-2×di) + r = 9(Σ(10i-2×di) + k) + r

即 Σdi 整除 9 的余数是 r 。

然后证明任意两个所有位数相同的十进制数的差是 9 的倍数。

∵ 两个数各位数字都相同,
∴ 各位数字的和也相同,
∴ 各位数字的和与9的余数也相同,
∴ 这两个数字整除 9 的余数相同,
∴ 这两个数字的差是 9 的倍数。

两个9的倍数的差也是9的倍数

去掉一个数字后,各位数的和为 9k – d,整除 9 的余数是 9 – d。

∵ 各位数的和为 9k + (9 – d)
∴ 各位数的和的各位数的和整除 9 的余数也是 9 – d。
∴ 最终的结果整除 9 的余数也是 9 – d。

其实从证明过程也可以看出,其实不管几位数都是可以的,不一定要 5 位数。

 

php 版简单 Trie 树

用 php 写了一个简单的 Trie 树,可以用来做字符串匹配。


<?php

$words = array(
'123','145','43'
);

class Trie {
    /**
     *
     * 节点数组。每个节点为二元组,依次为是否叶子节点,子节点.
     * @var array $nodes
     */
    protected $nodes;

    /**
     *
     * @var array $words 关键词数组
     */
    function __construct($words) {
        $this->nodes = array( array(false, array()) ); //初始化,添加根节点
        $p = 1; //下一个要插入的节点号
        foreach ($words as $word) {
            $cur = 0; //当前节点号
            for ($len = strlen($word), $i = 0; $i < $len; $i++) {
                $c = ord($word[$i]);
                if (isset($this->nodes[$cur][1][$c])) { //已存在就下移
                    $cur = $this->nodes[$cur][1][$c];
                    continue;
                }
                $this->nodes[$p]= array(false, array()); //创建新节点
                $this->nodes[$cur][1][$c] = $p; //在父节点记录子节点号
                $cur = $p; //把当前节点设为新插入的
                $p++; //
            }
            $this->nodes[$cur][0] = true; //一个词结束,标记叶子节点
        }
    }

    function match($s) {
        $ret = array();
        $cur = 0; //当前节点,初始为根节点
        $i = 0; //字符串当前偏移
        $p = 0; //字符串回溯位置
        $len = strlen($s);
        while($i < $len) {
            $c = ord($s[$i]);
            if (isset($this->nodes[$cur][1][$c])) { //如果存在
                $cur = $this->nodes[$cur][1][$c]; //下移当前节点
                if ($this->nodes[$cur][0]) { //是叶子节点,单词匹配!
                    $ret[$p] = substr($s, $p, $i - $p + 1); //取出匹配位置和匹配的词
                    $p = $i + 1; //设置下一个回溯位置
                    $cur = 0; //重置当前节点为根节点
                }
            } else { //不匹配
                $cur = 0; //重置当前节点为根节点
                $i = $p; //把当前偏移设为回溯位置
                $p = $i + 1; //设置下一个回溯位置
            }
            $i++; //下一个字符
        }
        return $ret;
    }
}

$trie = new Trie($words);
$s = '123456787654321';
$found = $trie->match($s, $trie);
print_r($found);

结果:

Array
(
    [0] => 123
    [11] => 43
)

不知道有没有 bug 。

123456789

星期五是8月7号。于是就有流传这天就有 12:34:56 07/08/09 ,也就是123456789。其实这个 123456789 还不够完美。首先就要取决于不同的区域的日期格式,还把时间写在了日期前面。

我看到了就说,这个没 09:09:09 09/09/09 好。炸弹比顺子大。

这次这台风也太不爽快。本来说星期六到,结果连续跳票。到现在也就是挂点风,然后过一会撒点水。难道真的要等到上班了才来么……