大整数乘法 求阶乘

来源:互联网 发布: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位了。


倒序存储:如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;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 亲戚家借钱不还怎么办 学习瑜伽教练口令好复杂怎么办 练瑜伽腿的柔韧性不够怎么办 瑜伽扭转时手抓不到脚怎么办 练瑜伽腿部太硬怎么办 褶皱衣服不紧了怎么办 吃撑了肚子涨怎么办 正好压本科线该怎么办 大脚趾被砸了怎么办 脊柱侧弯每天疼怎么办 内衣扣的位置脊柱疼怎么办 练完瑜伽颈椎疼怎么办 乳胶枕头太高了怎么办 枕头太高脖子痛怎么办 颈椎突出症状缓解后怎么办 外痔疼的的历害怎么办 小肚子疼得历害怎么办 练瑜伽伤到颈椎怎么办 鼻子干口干胃烧怎么办 颈椎病压迫神经引起手麻怎么办 4个月婴儿睡觉少怎么办 晚上睡觉睡不好老是醒来怎么办 吃了没熟的香蕉怎么办 70岁父母老吵架怎么办 怀孕七个月晚上睡不着怎么办 九个月宝宝睡眠不好怎么办 一个月的宝宝放不下怎么办 宝宝被吓了发烧怎么办 体内火气重睡不着觉怎么办 宝宝睡觉一直翻身发出声音怎么办 严重失眠怎么办整夜睡不着觉 腿疼得睡不着觉怎么办 19岁晚上睡不着该怎么办 工作累的想哭怎么办 心累迷茫想哭怎么办 白天很累晚上又睡不着怎么办 发型睡觉压乱了怎么办 通宵一夜第二天怎么办 夏天了腿脚还凉怎么办 咖啡色三天了月经还是下不来怎么办 睡觉姿势不对腰疼怎么办