输入n,计算S= 1! + 2! + 3!+...+n!的末六位(不含前导0)。n<=10^6。这里,n!表示前n个正整数之积。
这个题目取自《算法竞赛入门》,题目中有几个陷阱需要注意,1)溢出问题;2)效率问题
先看源代码:
#include <stdio.h>
#include <time.h>
void main()
{
const int MOD = 1000000;
int i,j,n,s = 0;
scanf("%d",&n);
if(n > 25) //25!的后六位全为0,不管怎么加,最后结果不变
n = 25;
for (i = 1;i <= n;i++)
{
int factorial = 1;
for(j = 1;j <= i;j++)
factorial = (factorial * j)%MOD;
s =(s + factorial) % MOD;
}
printf("%d\n", s);
printf("Time used = %.21f\n",(double) clock() / CLOCKS_PER_SEC);
}
几个值得学习的技巧:
1)用const声明一个常量,会比直接什么一个常量来得更好。比如:不会被改变,直观,容易修改等等。
2)要计算只包含加法、减法、乘法的整数表达式除以正整数n的余数,可以在每步计算之后对n 取余数。结果不变
比如上面要计算的是s的后六位,需要s对1000000取余数。但是考虑到阶乘后溢出的问题,在计算factorial的时候就直接取了余数
3)计时函数的使用。计时函数的使用可以直观的看到程序运行需要的时间,便于只管的验证算法的效率。但是要注意的是
a)调用clock()的时候,需要除以CLOCKS_PER_SEC,得到的结果才是需要的时间。CLOCKS_PER_SEC是一个跟操作系统有关的常数。
b)由于clock()是从程序运行就开始计时,键盘输入的时间也算在内,为避免人为因素的影响,可以在控制台下使用“echo 输入数据|程序名” 这个命令来运行程序
eg:
命令提示符下键入:
echo 10|abc
运行的程序名为abc,输入的数据为10 。这里面用到了管道命令:| 其含义为前一个命令的输出作为后一个命令的输入。echo是回显命令,刚开始还以为是为了解决显示问题,后来想想应该是为了解决系统控制台不识别 10|abc之类的命令。