秦朝末年,楚汉相争,韩信率兵打仗。某次,他急需点兵迎战,就命士兵布阵三次(命3人一排,多出2名;命5人一排,多出3名;命7人一排,多出2名)后,直言有1073名勇士可击垮敌兵,其神机妙算鼓舞士气,旌旗摇动,大败楚军。
首先这个故事的真实性很低。因为1000多名士兵布成10×10方阵也只有10个,剩下73人再排10人队就很好数。用这种简单的方法要比全军布阵3次更快速。
其次故事中的方法在如今也不是最聪明的方法。因为令n人一排取余,再取其中完整的一队重复此算法,即可得到n进制数的表达。这个方法在面对天文数字时的处理速度应该是最快的。
故事中的方法在如今也不是最实用的方法。因为报数要比自己去算更快。
最后故事中的方法没有唯一解。以下是对此问题无任何经验时,最简单的算法。
int _3 = 2, _5 = 3, _7 = 2;
for (int t = 0; t < 10000; ++t) {
if (_3 == _5 && _5 == _7) {
System.out.print(_3+" ");
}
int min = StaticMathUtils.min(_3, _5, _7);
if (min == _3) {
_3 += 3;
}
if (min == _5) {
_5 += 5;
}
if (min == _7) {
_7 += 7;
}
}
得到的结果为:23 128 233 338 443 548 653 758 863 968 1073 1178 1283 1388 1493 1598 1703 1808 1913 2018 2123 2228 2333 2438 2543 2648 2753 2858 2963 3068 3173 3278 3383 3488 3593 3698 3803 3908 4013 4118 4223 4328 4433 4538 4643 4748 4853 4958 5063 5168 5273 5378 5483 5588 5693 5798 5903 6008 6113 6218 6323 6428 6533 6638 6743 6848 6953 7058 7163 7268 7373 7478 7583 7688 7793 7898 8003 8108 8213 8318 8423 8528 8633 8738 8843 8948 9053 9158 9263 9368 9473 9578 9683 9788 9893 9998 10103 10208 10313 10418 10523 10628 10733 10838 10943 11048 11153 11258 11363 11468 11573 11678 11783 11888 11993 12098 12203 12308 12413 12518 12623 12728 12833 12938 13043 13148 13253 13358 13463 13568 13673 13778 13883 13988 14093 14198 14303 14408 14513 14618 14723 14828 14933 15038 15143 15248 15353 15458 15563 15668 15773 15878 15983 16088 16193 16298 16403 16508 16613 16718 16823 16928 17033 17138 17243 17348 17453 17558 17663 17768 17873 17978 18083 18188 18293 18398
分辨率为105,即3、5、7的最小公倍数。知道这个规律后,只要试出最小那个符合条件的数,就可以写出公式了。此案例的公式为:n = 23 + 105 × m。它是一个通解,如果韩信真用这个方法,那他目测的分辨率应达到105才行。
如果史实如此,想必不是通过解算方程或者试验的方法得到的,而是韩信有数一下大概有多少排。这个技能是许多出纳都具备的,有难度但不稀有。1073排7排就有153列。如果10排为1方阵,就有15方阵余3排零2人。其实就是这么数出来的再验算一下,然后故弄玄虚,使人生疑。这个算法更像是冗余校验算法而不是快速计数算法。