实例:输入n,计算S = 1! + 2! + 3! + 4! + ... + n!的末六位(不含前导0)。其中 n ≤ 106

分析:考虑到数据溢出后程序如下:

#include <stdio.h>
int main(void)
{
int n, i;
int sum = ;
int factorial = ;
scanf("%d", &n); for(i = ; i <= n; i++)
{
factorial = (factorial * i) % ;
sum = (sum + factorial) % ;
} printf("%d\n", sum); return ;
}

作者源程序如下:

#include <stdio.h>
#include <time.h>
int main(void)
{
const int MOD = ;
int i, j, n, S = ;
scanf("%d", &n); for(i = ; i<= n; i++)
{
int factorial = ;
for(j = ; j <= i; j++)
factorial = (factorial * j % MOD);
S = (S + factorial) % MOD;
} printf("%d\n", S % );
printf("Time used = %.2lf\n", (double)clock() / CLOCKS_PER_SEC); return ;
}

值得借鉴的是该程序可以计时,使用time.h库中的函数clock()函数返回程序目前为止运行时间,该时间除以常数CLOCKS_PER_SEC得到的值以"秒"为单位。其中常数CLOCKS_PER_SEC和操作系统相关。因此不要直接使用clock()的返回值。据此,我们在程序结束之前调用该函数,就可以得到整个程序的运行时间。

一个问题是我们通过命令行运行程序的时候键盘输入时间也被计算在内。我们利用管道来避免键盘输入时间对测试结果的干扰。Windows系统中,在编译好的程序所在目录下执行命令行命令 echo 20 | FactSum,其中20是要输入的数据,FactSum是程序名。这样操作系统会自动帮我们把20输入程序,因此可以避免键盘输入时间。

关于算法的运行时间分析我在这里做了一些详细得论述,因此我们可以直接得出结论:该算法的运行时间为O(N2),我写的第一个程序是线性时间O(N)。

下面我们来检验一下分析是否正确,一般有两种常用方法可以采用:

一种是编程并比较实际观察到的运行时间与通过分析所描述的运行时间是否相匹配。当N扩大一倍时,线性程序的运行时间乘以因子2,二次程序的运行时间乘以因子4等等。

验证一个程序是否是O(f(N))的另一个常用的技巧是对N的某个范围(通常用2的倍数隔开),计算比值 T(N) / f(N),其中T(N)是实际运行时间。如果f(N)是运行时间的理想近似,那么算出的值收敛于一个正常数。如果f(N)估计过大,则算出的值收敛于零。如果f(N)估计过低,那么算出的值发散。

最后多次测试,根据运行时间表可以得到程序的运行时间,与我们的分析比较即可,这里涉及作图,并且不同配置的机器实际运行时间都有差别,因此运行时间表就在此省略了。另外在本机上多次测试50000得到的平均运行时间是运行时间是17.60,由此我们可以大胆预测,输入为n = 10^6时,程序需要运行17.60*(10^6/ 50000)^2秒,约为1.96个小时程序才能跑完(另:第一个线性时间的程序几乎是瞬间给出了答案)。那么如何解决这个问题呢,一个就是直接用第一个程序,另一个就需要一点观察力了,我们做出一张输出结果表,发现从n=25开始,结果都不变,为940313。我们可以写一个程序求出25!发现其末尾有6个零,所以从第25项开始,后面所有的项都不影响和的末6位数字,因此在该程序的最前面加上一条语句:if(n > 25) n = 25;这样效率和溢出都不成问题了。

All Rights Reserved.
Author:海峰:)
Copyright © xp_jiang.
转载请标明出处:http://www.cnblogs.com/xpjiang/p/4153672.html
参考资料:
《算法竞赛入门经典》——刘汝佳
《数据结构与算法分析:C语言描述_原书第二版》——Mark Allen Weiss

阶乘之和 & 程序运行时间 & 算法分析的更多相关文章

  1. HPU 第三次积分赛:阶乘之和(水题)

    阶乘之和 描述 对于整数pp,给出以下定义 p=x_{1}!+x_{2}!+x_{3}!+...+x_{q}!(x_{i}<x_{j}for\ all\ i<j )p=x1​!+x2​!+ ...

  2. 7.20试机测 T3 阶乘之和 暴力AC题解

    7.20试机测  T3 阶乘之和 暴力AC题解 题外话:此乃本蒟蒻发表的第一篇题解,大家多多关照,支持一下,谢谢 题面 3.阶乘之和(sum.pas/in/out) 问题描述: 给定一个非负整数 n, ...

  3. 在 Linux 如何优雅的统计程序运行时间?恕我直言,你运行的可能是假 time

    最近在使用 time 命令时,无意间发现了一些隐藏的小秘密和强大功能,今天分享给大家. time 在 Linux 下是比较常用的命令,可以帮助我们方便的计算程序的运行时间,对比采用不同方案时程序的运行 ...

  4. 检测Java程序运行时间的2种方法(高精度的时间[纳秒]与低精度的时间[毫秒])

    第一种是以毫秒为单位计算的. 代码如下: long startTime=System.currentTimeMillis(); //获取开始时间 doSomeThing(); //测试的代码段 lon ...

  5. nyoj 91 阶乘之和(贪心)

    阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...

  6. ACM 阶乘之和

    阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...

  7. 阶乘之和--nyoj91

    描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3!,如果是,则输出Yes,否则输出No: 输入 第一行有一个整数0<m<10 ...

  8. PAT乙级 1026. 程序运行时间(15)

    1026. 程序运行时间(15) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 要获得一个C语言程序的运行时间, ...

  9. nyoj 91 阶乘之和

    点击打开链接 阶乘之和 时间限制:3000 ms  |  内存限制:65535 KB 难度: 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2 ...

随机推荐

  1. 用宏 x y z,找出最大值最小值

    #define max(x,y,z) ((x)>(y)?(x):(y))>(z)?((x)>(y)?(x):(y)):(z) #define min(x,y,z) ((x)<( ...

  2. Bootstrap页面布局22 - BS工具提示

    当鼠标点击在一个a连接上时,显示提示文字的效果 ----------------  tooltip <div class='container-fluid'> <h3 class=' ...

  3. [转]百度MP3音乐API接口及应用

    当你在百度去搜索一首歌时,你会发现有种更简单的方法,嘿嘿,告诉你个秘密,百度有个不公开的API http://box.zhangmen.baidu.com/x?op=12&count=1&am ...

  4. 【转】Unity LayerMask 的位运算

    Unity的Layer Unity是用 int32来表示32个Layer层,int32用二进制来表示一共有32位. 0000 0000 0000 0000 0000 0000 0000 0000 31 ...

  5. easy UI简单使用介绍

    http://www.cnblogs.com/yokoboy/archive/2012/12/06/2806132.html

  6. IIS8中部署WCF服务出错:HTTP 错误 404.3 - Not Found

    解决方法,以管理员身份进入命令行模式,运行: "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ ...

  7. 最大子序列和 o(n)

    问题: 给定一整数序列A1, A2,... An (可能有负数),求A1~An的一个子序列Ai~Aj,使得Ai到Aj的和最大 例如:整数序列-2, 11, -4, 13, -5, 2, -5, -3, ...

  8. js合计

    Js合计行: 可以先循环行,然后按行获取这行带有你定义的class的td,取得这些td的 text后相加,最终赋值到这行的“合计”单元格就行了 var trslength = $("#dat ...

  9. WordPress显示备案号

    备案时,需要显示备案号,而wordpress默认模板本身不带这个信息,为了更快速应付备案,解决方案如下: 根据wp-config.php的提示 .......... /** * zh_CN本地化设置: ...

  10. Selenium2学习-004-WebUI自动化实战实例-002-百度登录

    此文主要通过 百度登录 功能,进行 Selenium2 的实战实例讲解.文中所附源代码于 2015-01-17 23:33 亲测通过,敬请亲们阅览.同时,您也可参考此文进行其他网站(例如 京东.易迅. ...