舍罕王的失算 – 不可忽視的總合和乘績
(Shirham)舍罕王因為裝B,想給宰相提要求自已要的賞賜。宰相理所當然的就提出了B到天邊的要求:
- 在8X8的格子裏每天放麥子,第一格1粒,第2格2粒,第3格4粒,每一天都比前一天多一倍的數量,直到64天結束。
這是個等比級數求合的問題。 $Sum = 2^0+2^1+2^2+2^3+2^4+….+2^{63}$
古代裝B在現代看來還是可以的,但是身為攻城師,也要有裝B的大絕才行,程式設計上有什麼可以優化的都給他用上… Google 一下,當公比不為1時,等比數列的求和公式為 $Sn=\frac{[a1(1-q^n)]}{(1-q)}$ 嗯裝B公式找到了… 程式就可以改為:
sum = 1(1-2^63)/1-2; // 當q等於2時 == 2^63 - 1
一行搞定!
這就告訴了我們數學很重要…裝B打臉需要它!
程式的設計:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
void main()
{
double t,s;
int i,j;
clock_t t1 = clock();
for (j=0;j<1000000;j++) {
t = 1;
s = 1;
for(i = 2;i < 64 ;i++) {
t = t * 2;
s = s + t;
}
}
clock_t t2 = clock();
clock_t time = t2 - t1;
printf("總麥粒數為:%f\n",s);
printf("Completed in %ld \n", time);
t1 = clock();
for (j=0;j<1000000;j++) {
s = pow(2,63)-1;
}
t2 = clock();
time = t2 - t1;
printf("總麥粒數為:%f\n",s);
printf("Completed in %ld \n", time);
}
// output
總麥粒數為:9223372036854775800.000000
Completed in 568
總麥粒數為:9223372036854775800.000000
Completed in 6