网友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的文本文件,的确很烦恼。
注释都乱码了