- UID
- 2198
注册时间2005-6-29
阅读权限255
最后登录1970-1-1
副坛主
该用户从未签到
|
楼主 |
发表于 2009-9-22 00:50:27
|
显示全部楼层
经小齐授权 发一份小齐写的算法含部分优化(10倍数)的代码
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#define MAX 100000
int condition(int n)
{
if (n < 1)
{
printf("对不起,程序计算的范围之内 !\r\n") ;
return 0;
}
if (n > 20000)
{
printf("别玩了,这么大的数算来也没什么用呀!\r\n") ;
return 0;
}
return 1;
}
// count 后面零的个数
void display(int *p, int len, int count)
{
int i = len - 1;
printf("%d", *(p+i)) ;
for (i--; i >= 0; --i)
{
printf("%05d", *(p+i));
}
for (i = 0; i < count; ++i)
{
printf("0") ;
}
printf("\r\n");
}
int getLen(int n)
{
int i,
len ;
double bit = 1.0 ;
for (i = 1; i <= n ; ++i)
{
bit += log10(i) ;
}
// 一位整形保存5位,所以除5,多加二位,防止溢出
len = (int)bit / 5 + 2;
return len ;
}
void compute(int n)
{
int i ,
j ,
k ,
len,
size,
count,
state;
int *p ;
DWORD begin = GetTickCount() ;
size = getLen(n) ;
p = (int *)malloc(sizeof(int)*size) ;
memset(p, 0, sizeof(int)*size) ;
p[0] = len = 1 ;
count = 0;
//state = 0 ;
begin = GetTickCount() ;
for (i = 2; i <= n; ++i)
{
// 优化10的倍数,如果是10的话,不参加运算,直接count+1
// 也可以自己取出2、5来配对减少乘的次数
state = 0;
for (k = i; k % 10 == 0 && k >= 10; k /= 10)
{
++count ;
}
if (k == 1)
{
continue;
}
for (j = 0; j < len; ++j)
{
p[j] = p[j] * k + state;
state = p[j] / MAX ;
p[j] %= MAX ;
}
p[j] += state ;
if (p[len])
{
++len;
}
if (len >= size)
{
printf("OverFlow!\r\n") ;
return ;
}
}
display(p, len, count) ;
free(p) ;
printf("used time: %ld ms\r\n", (GetTickCount() - begin)) ;
}
int main(int argc, char **argv)
{
int n;
while (scanf("%d", &n) > 0 && condition(n) == 1)
{
compute(n) ;
}
return 0;
} |
|