实例:输入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. 【IOS笔记】Using View Controllers in Your App

    参考:http://www.cnblogs.com/patientAndPersist/p/3279645.html Using View Controllers in Your App Whethe ...

  2. JNDI学习总结(一)——JNDI数据源的配置

    一.数据源的由来 在Java开发中,使用JDBC操作数据库的四个步骤如下:   ①加载数据库驱动程序(Class.forName("数据库驱动类");) ②连接数据库(Connec ...

  3. Bootstrap页面布局21 - BS对话框设计

    设计弹出层对话框: 设计一个点击登录按钮,再弹出一个登陆对话框的实例,且带有动画效果 <div class='container-fluid'> <h2 class='page-he ...

  4. XPath学习:轴(14)——总结

    原文地址:http://www.cnblogs.com/zhaozhan/archive/2009/09/10/1564396.html XPath 是一门在 XML 文档中查找信息的语言.XPath ...

  5. volatile in thread

    public class TestCalc { public static void main(String[] args) { class StoppableThread extends Threa ...

  6. 转:自定义ASP.NET MVC Html辅助方法

    在ASP.NET MVC中,Html辅助方法给我们程序员带来很多方便,其重要性也就不言自明.有时候,我们不想重复地写一些HTML代码,或者MS没有提供我们想要的那个HTML标签的Html辅助方法,那么 ...

  7. Celery - Best Practices

    If you've worked with Django at some point you probably had the need for some background processing ...

  8. margin负值

    一列li并排的时候,需要一些间距的时候,又不需要最右边或者最左边有间距. <!DOCTYPE html> <html lang="zh-CN"> <h ...

  9. Group GridView:用于.Net的分组显示的GridView

    我的项目需要一个可以分组显示的GridView,我不会写,上网找了一圈,最终在国外的网站上找到的这个,比较符合我的要求,但它的分页得重写,它写了能分页,但我发现它的分页功能事实上并没有实现,也不知道是 ...

  10. eclipse for hello world makefile

    1. 工程文件分析 使用eclipse新建一个Hello World工程,假设工程名称是hello,此时eclipse在工程目录下新建了一个名为hello的文件夹: hello/ .cproject ...