网友Mutalisk给的一道题目,
计算 (1+2^0)*(1+2^1)*(1+2^2)…(1+2^32)
今晚赶回家了,花了几十分钟写好了代码,计算结果和Mutalisk的一样。运行时间为10毫秒,当然,是在我PIII 900Mhz的机子上,基本上一闪就出结果。
我的结果是160位,
41900194778866063098
69616409977680717118
75372548418310142014
25167533420258842344
35351687855236795051
88646940175563375578
68147135401121187966
16074978167792968750
内容:
#include <windows.h> #include <stdio.h> #include <string.h> #include <stdlib.h> struct big_number{ int d[64]; // 4*64 256λ int len; }exp2[40], ans; void print( big_number & b ) { int i, j; for( i=b.len-1; i>=0; i-- ){ for( j=1000; j>=1; j/=10 ) if( !(i==b.len-1 && j>1 && b.d[i]<j ) ) printf("%d", (b.d[i]/j)%10 ); } } void mul( big_number & b, int a ) { int i, r; r = 0; for( i=0; i<b.len; i++ ){ r = r + b.d[i] * a; b.d[i] = r % 10000; r /= 10000; } //ÏÂÃæÑ»·¿ÉÒÔÓÅ»¯ while( r>0 ){ b.d[b.len++] = r % 10000; r /= 10000; } } void mul2( big_number &a, big_number &b ) { int i, j, k, p, r; big_number c; //result memset( &c, 0, sizeof(c) ); for( i=0; i<b.len; i++ ){ p = b.d[i]; for( k=0, j=i, r=0; k<a.len; k++, j++ ){ r = r + a.d[k] * p + c.d[j]; c.d[j] = r % 10000; r /= 10000; } //ÏÂÃæÑ»·¿ÉÒÔÓÅ»¯È¥µô while( r>0 ){ r = c.d[j] + r; c.d[j] = r % 10000; r /= 10000; j ++; } c.len = j; } a = c; } void add( big_number & a, big_number & b ) { int i, r; r = 0; a.len = a.len<b.len ? b.len : a.len; for( i=0; i<a.len; i++ ){ r = r + a.d[i] + b.d[i]; a.d[i] = r % 10000; r /= 10000; } //ÏÂÃæÒ»²œ¿ÉÒÔÓÅ»¯ while( r>0 ){ a.d[a.len++] = r % 10000; r /= 10000; } } int is_bigger( big_number & a, big_number & b ) { if( a.len > b.len ) return 1; else if( a.len < b.len ) return 0; int i; for( i=a.len-1; i>=0; i-- ){ if( a.d[i] > b.d[i] ) return 1; else if( a.d[i] < b.d[i] ) return 0; } return 0; } //ŒÆËã2µÄ·œ void prepare() { int i,j; memset( &exp2[0], 0, sizeof(big_number) ); exp2[0].d[0] = 1; exp2[0].len = 1; for( i=1; i<=32; i++ ){ exp2[i] = exp2[i-1]; add( exp2[i], exp2[i-1] ); //ŒÓ·š±È³Ë·š¿ì //mul( exp2[i], 2 ); } } //ŒÆËã (1+2^0)*(1+2^1)*(1+2^2)...(1+2^32) void work() { int i; big_number t; memset( &ans, 0, sizeof(ans) ); memset( &t, 0, sizeof(t) ); t.d[0] = 1; t.len = 1; ans.d[0] = 1; ans.len = 1; for( i=0; i<=32; i++ ){ add( exp2[i], t ); // + 1 mul2( ans, exp2[i] ); } print( ans ); } int main() { int n=GetTickCount(); prepare(); work(); printf("\nTime used: %dmm\n", GetTickCount()-n ); system("pause"); return 0; }
还可以优化的,特别是余数处理,我没时间去做。
哈哈,还是你的方法好啊。家里的机器的浏览器好像有问题,你的文章都看不全,只能看一小半
比起你的来,我的那个就太冗余了,400+行代码。
虽然也只用了16ms。但是毕竟我的机器比较好
对你越来越有兴趣·
请尝试用MMX或SSE指令内联做,你会得到更好的效率
struct big_number{
int d[64]; // 4*64 256位
int len;
}exp2[40], ans
从这里可以看出ans最大表示2^256-1的数。但是(1+2^0)*(1+2^1)*(1+2^2)…(1+2^32) > (2^0)*(2^1)*(2^2)…(2^32)=2^(32*33/2)=2^528.
我搞错了。ans能最大表示2^(256*8)-1
答案不是2^64-1么?把二进制的64个一转化为十进制不就可以了?
我用python写的4ms,只有7行
Windows的GetTickCount()计算不了比10ms小的时间。
阿阿。菜鸟我也边学边写个python的,看来结果和你一样的,写对了
hp@debian:~/Desktop$ time python ./aa.py
4190019477886606309869616409977680717118753725484183101420142516753342025884234435351687855236795051886469401755633755786814713540112118796616074978167792968750
real 0m0.019s
user 0m0.016s
sys 0m0.004s
"<" “>”没被替换,怪不得代码看起来不完整了
@osbin:已经更正,现在代码完整了,也好看了!!
注释变乱码了
不好意思。。。我在linux用gedit看gbk的文本文件,的确很烦恼。
注释都乱码了