大整数乘法 求阶乘
来源:互联网 发布:mac 的.m2文件夹 编辑:程序博客网 时间:2024/06/11 02:40
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1042
N!
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24886 Accepted Submission(s): 6897
Problem Description
Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!
Input
One N in one line, process to the end of file.
Output
For each N, output N! in one line.
Sample Input
123
Sample Output
126
解题思路: 算法来源于一篇博客的介绍---“列表法”。http://blog.csdn.net/amossavez/article/details/4312399
也就是说我们在计算生成这个二维表时,不必一位一位地乘,而可以三位三位地乘;在累加时也是满1000进位。这样,我们在计算 m位整数乘以 n位整数,只需要进行 m x n / 9次乘法运算,再进行约(m + n) / 3次加法运算和(m + n) /3 次取模运算。总体看来,效率约是前一种算法的 9倍。
有人可能会想:既然能够三位三位地乘,为什么不4位 4位甚至5位5位地乘呢?那不是可以提高 16 乃至 25 倍效率吗?听我解来:本算法在累加表中斜线间的数字时,如果用无符号长整数(范围 0至~4294967295)作为累加变量,在最不利的情况下(两个乘数的所有数字均是 9),能够累加约4294967295/(999*999)=4300 次,也就是能够准确计算任意两个均不超过 12900(每次累加的结果"值"三位,故 4300*3=12900)位的整数相乘。如果 4 位 4 位地乘,在最不利的情况下,能够累加约4294967295/(9999*9999)=43 次,仅能够确保任意两个不超过 172 位的整数相乘,没有什么实用价值,更不要说5位了。
有人可能会想:既然能够三位三位地乘,为什么不4位 4位甚至5位5位地乘呢?那不是可以提高 16 乃至 25 倍效率吗?听我解来:本算法在累加表中斜线间的数字时,如果用无符号长整数(范围 0至~4294967295)作为累加变量,在最不利的情况下(两个乘数的所有数字均是 9),能够累加约4294967295/(999*999)=4300 次,也就是能够准确计算任意两个均不超过 12900(每次累加的结果"值"三位,故 4300*3=12900)位的整数相乘。如果 4 位 4 位地乘,在最不利的情况下,能够累加约4294967295/(9999*9999)=43 次,仅能够确保任意两个不超过 172 位的整数相乘,没有什么实用价值,更不要说5位了。
倒序存储:如res[]={312,658,7} two[]={564,2}
代码如下:
#include <iostream>#include <iomanip>using namespace std;unsigned int *res,*temp;int two[2];int digit;void mult(int x){int twoN;unsigned int *p=0;if(x>999){two[0]=x%1000;two[1]=x/1000;twoN = 2;}else{two[0]=x;twoN=1;}int c=0;int i,j,maxj;//cout<<"two: "<<two[0]<<","<<two[1]<<" --"<<twoN<<endl;for(i=0;i<digit+twoN-1;i++){if(i-digit+1>0)j=i-digit+1;else j=0;maxj = i+1 > twoN ? twoN:i+1;for(;j<maxj;j++){c = c + two[j]*res[i-j];}temp[i]=c%1000;c = c/1000; //cout<<">>>> i:"<<i<<" temp[i]:"<<temp[i]<<endl;}if(c){temp[i]=c;digit=i+1;}else digit=i;p=res;res=temp;temp=p;}int main(){//freopen("out.txt","w",stdout);int n,i;res=(unsigned int *)malloc(sizeof(int)*15000);temp=(unsigned int *)malloc(sizeof(int)*15000);while(cin>>n){if(n==0){cout<<1<<endl;continue;}memset(res,0,sizeof(int)*15000);if(n>999){res[0]=n%1000;res[1]=n/1000;digit=2;}else {res[0] = n;digit = 1;}for(i=n-1;i>1;i--){mult(i);}//cout<<"digit:"<<digit<<endl;cout<<res[digit-1];for(i=digit-2;i>=0;i--){cout<<setfill('0')<<setw(3)<<res[i];}cout<<endl;}return 0;}
- 大整数乘法 求阶乘
- 求大整数的阶乘
- 求大整数的阶乘
- 求大整数的阶乘
- 求大整数的阶乘
- 大整数问题,乘法,加法,阶乘
- 大整数的乘法与阶乘运算
- 求大整数的阶乘(hdu1042)
- 求大整数的阶乘的方法
- N的阶乘 -- (九度OJ 大整数乘法)
- Java 实现大整数加法、乘法、阶乘运算
- 练习系统 实验三 求大整数的阶乘
- 超精度运算之大整数求阶乘
- 大整数阶乘计算
- 大整数的阶乘
- 大整数阶乘
- 大整数的阶乘
- 大整数阶乘
- 理解和解决IE的内存泄漏模式
- 古老的文明之城―都灵
- 美国妇女不慎将价值7.8万美元钻戒掉入下水道
- POJ1149 PIGS 题解
- Linux系统不响应SYN包的解决办法
- 大整数乘法 求阶乘
- 一周就是那样吗
- hibernate tools for eclipse 反向数据库
- 日本大地震的真正起因!!!
- 感慨
- 力争上游 ——我眼中的“计算机产业链”
- javascript location.hash
- 分享我爱听的音乐《如果》
- 幻想FPGA人工智能的未来世界