日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

回《笔试常见的“阶乘”编程题,你写对了么?》

發(fā)布時間:2025/5/22 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 回《笔试常见的“阶乘”编程题,你写对了么?》 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原帖鏈接:http://www.cnblogs.com/kym/archive/2009/10/05/1578224.html????
????我機器上沒有C#的開發(fā)環(huán)境,所以沒法測試作者這個代碼的耗時,不過10000的階乘在5秒內(nèi)完成,不知道作者的代碼是否能達到?我想起前段時間在HDU做的一道ACM題,題目的時限要求是1秒內(nèi)能計算10000的階乘(當然這是代碼跑在它的服務(wù)器的時間)。

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1042

????? 如果按照飛林沙文章中那種常規(guī)的思路,逐位相乘,再對齊相加,缺點很明顯,如果n值比較大,運算次數(shù)將非常多,必定會超時,1萬的階乘想在1秒內(nèi)完成肯定無法達成。
???
我的思路是把數(shù)據(jù)分組,每組上限為9999,最多可容納2萬組,每組4位整數(shù),則可以容納8萬位整數(shù)(當然,組數(shù)可以隨你要計算的n的大小進行調(diào)整),利用組與組的錯位相乘再相加,可以避免樓主這樣逐位進行運算。

代碼如下:

  • #include<iostream>?
  • #include<stdio.h>?
  • #include<string>?
  • #include<iomanip>?
  • #include<algorithm>?
  • using?namespace?std; ?
  • #include?"time.h" ?
  • ?
  • const?int?MAX_GROUPS?=?20000;//最多2萬組,每組最多4位整數(shù),即最多可容納8萬位整數(shù) ?
  • const?int?MAXN?=?9999;//每組的上限值 ?
  • const?int?GROUP_LEN?=?4;//每組的最大長度 ?
  • ?
  • class?BigInteger ?
  • { ?
  • private: ?
  • ????int?data[MAX_GROUPS]; ?
  • ????int?len; ?
  • ????void?init() ?
  • ????{ ?
  • ????????memset(data,0,sizeof(data)); ?
  • ????} ?
  • public: ?
  • ????BigInteger() ?
  • ????{ ?
  • ????????init(); ?
  • ????????len?=?0; ?
  • ????} ?
  • ????BigInteger(const?int?b); ?
  • ????BigInteger(const?BigInteger?&); ?
  • ?
  • ????bool?operator?>?(const?BigInteger&)const; ?
  • ????BigInteger?&?operator=(const?BigInteger?&); ?
  • ????BigInteger?&?add(const?BigInteger?&); ?
  • ????BigInteger?&?sub(const?BigInteger?&); ?
  • ????BigInteger?operator+(const?BigInteger?&)?const; ?
  • ????BigInteger?operator-(const?BigInteger?&)?const; ?
  • ????BigInteger?operator*(const?BigInteger?&)?const; ?
  • ????BigInteger?operator/(const?int?&)?const; ?
  • ????void?print(); ?
  • }; ?
  • BigInteger::BigInteger(const?int?num) ?
  • { ?
  • ????int?res,tmp?=?num; ?
  • ????len?=?0; ?
  • ????init(); ?
  • ????while(tmp?>?MAXN) ?
  • ????{ ?
  • ????????res?=?tmp?-?tmp?/?(MAXN?+?1)?*?(MAXN?+?1); ?
  • ????????tmptmp?=?tmp?/?(MAXN?+?1); ?
  • ????????data[len++]?=?res; ?
  • ????} ?
  • ????data[len++]?=?tmp; ?
  • } ?
  • BigInteger::BigInteger(const?BigInteger?&?rhs)?:?len(rhs.len) ?
  • { ?
  • ????int?i; ?
  • ????init(); ?
  • ????for(i?=?0?;?i?<?len?;?i++) ?
  • ????{ ?
  • ????????data[i]?=?rhs.data[i]; ?
  • ????} ?
  • } ?
  • bool?BigInteger::operator?>?(const?BigInteger?&rhs)const ?
  • { ?
  • ????int?ln; ?
  • ????if(len?>?rhs.len) ?
  • ????{ ?
  • ????????return?true; ?
  • ????} ?
  • ????else?if(len?<?rhs.len) ?
  • ????{ ?
  • ????????return?false; ?
  • ????} ?
  • ????else?if(len?==?rhs.len) ?
  • ????{ ?
  • ????????ln?=?len?-?1; ?
  • ????????while(data[ln]?==?rhs.data[ln]?&&?ln?>=?0)? ?
  • ????????{ ?
  • ????????????ln--; ?
  • ????????} ?
  • ????????if(ln?>=?0?&&?data[ln]?>?rhs.data[ln])? ?
  • ????????{ ?
  • ????????????return?true; ?
  • ????????} ?
  • ????????else? ?
  • ????????{ ?
  • ????????????return?false; ?
  • ????????} ?
  • ????} ?
  • ?
  • } ?
  • ?
  • BigInteger?&?BigInteger::operator?=?(const?BigInteger?&rhs) ?
  • { ?
  • ????init(); ?
  • ????len?=?rhs.len; ?
  • ????for(int?i?=?0?;?i?<?len?;?i++) ?
  • ????{ ?
  • ????????data[i]?=?rhs.data[i]; ?
  • ????} ?
  • ????return?*this; ?
  • } ?
  • BigInteger&?BigInteger::add(const?BigInteger?&rhs) ?
  • { ?
  • ????int?i,nLen; ?
  • ?
  • ????nLen?=?rhs.len?>?len???rhs.len?:?len; ?
  • ????for(i?=?0?;?i?<?nLen?;?i++) ?
  • ????{ ?
  • ????????data[i]?=?data[i]?+?rhs.data[i]; ?
  • ????????if(data[i]?>?MAXN) ?
  • ????????{ ?
  • ????????????data[i?+?1]++; ?
  • ????????????data[i]?=?data[i]?-?MAXN?-?1; ?
  • ????????} ?
  • ????} ?
  • ????if(data[nLen]?!=?0)? ?
  • ????{ ?
  • ????????len?=?nLen?+?1; ?
  • ????} ?
  • ????else? ?
  • ????{ ?
  • ????????len?=?nLen; ?
  • ????} ?
  • ?
  • ????return?*this; ?
  • } ?
  • BigInteger?&?BigInteger::sub(const?BigInteger?&rhs) ?
  • { ?
  • ????int?i,j,nLen; ?
  • ????if?(len?>?rhs.len) ?
  • ????{ ?
  • ????????for(i?=?0?;?i?<?nLen?;?i++) ?
  • ????????{ ?
  • ????????????if(data[i]?<?rhs.data[i]) ?
  • ????????????{ ?
  • ????????????????j?=?i?+?1; ?
  • ????????????????while(data[j]?==?0)?j++; ?
  • ????????????????data[j]--; ?
  • ????????????????--j; ?
  • ????????????????while(j?>?i) ?
  • ????????????????{ ?
  • ????????????????????data[j]?+=?MAXN; ?
  • ????????????????????--j; ?
  • ????????????????} ?
  • ????????????????data[i]?=?data[i]?+?MAXN?+?1?-?rhs.data[i]; ?
  • ????????????} ?
  • ????????????else? ?
  • ????????????{ ?
  • ????????????????data[i]?-=?rhs.data[i]; ?
  • ????????????} ?
  • ????????} ?
  • ????????len?=?nLen; ?
  • ????????while(data[len?-?1]?==?0?&&?len?>?1)? ?
  • ????????{ ?
  • ????????????--len;???? ?
  • ????????} ?
  • ????} ?
  • ????else?if?(len?==?rhs.len) ?
  • ????{ ?
  • ????????for(i?=?0?;?i?<?len?;?i++) ?
  • ????????{ ?
  • ????????????data[i]?-=?rhs.data[i]; ?
  • ????????} ?
  • ????????while(data[len?-?1]?==?0?&&?len?>?1)? ?
  • ????????{ ?
  • ????????????--len;???? ?
  • ????????} ?
  • ????} ?
  • ????return?*this; ?
  • } ?
  • BigInteger?BigInteger::operator+(const?BigInteger?&?n)?const? ?
  • { ?
  • ????BigInteger?a?=?*this; ?
  • ????a.add(n); ?
  • ????return?a; ?
  • } ?
  • BigInteger?BigInteger::operator-(const?BigInteger?&?T)?const ?
  • { ?
  • ????BigInteger?b?=?*this; ?
  • ????b.sub(T); ?
  • ????return?b; ?
  • } ?
  • BigInteger?BigInteger::operator?*?(const?BigInteger?&rhs)?const ?
  • { ?
  • ????BigInteger?result; ?
  • ????int?i,j,up; ?
  • ????int?temp,temp1; ?
  • ?
  • ????for(i?=?0;?i?<?len;?i++) ?
  • ????{ ?
  • ????????up?=?0; ?
  • ????????for(j?=?0;?j?<?rhs.len;?j++) ?
  • ????????{ ?
  • ????????????temp?=?data[i]?*?rhs.data[j]?+?result.data[i?+?j]?+?up; ?
  • ????????????if(temp?>?MAXN) ?
  • ????????????{ ?
  • ????????????????temptemp1?=?temp?-?temp?/?(MAXN?+?1)?*?(MAXN?+?1); ?
  • ????????????????up?=?temp?/?(MAXN?+?1); ?
  • ????????????????result.data[i?+?j]?=?temp1; ?
  • ????????????} ?
  • ????????????else? ?
  • ????????????{ ?
  • ????????????????up?=?0; ?
  • ????????????????result.data[i?+?j]?=?temp; ?
  • ????????????} ?
  • ????????} ?
  • ????????if(up?!=?0) ?
  • ????????{ ?
  • ????????????result.data[i?+?j]?=?up; ?
  • ????????} ?
  • ????} ?
  • ????result.len?=?i?+?j; ?
  • ????while(result.data[result.len?-?1]?==?0?&&?result.len?>?1)?result.len--; ?
  • ????return?result; ?
  • } ?
  • BigInteger?BigInteger::operator/(const?int?&?b)?const ?
  • { ?
  • ????BigInteger?ret; ?
  • ????int?i,down?=?0; ?
  • ?
  • ????for(i?=?len?-?1?;?i?>=?0?;?i--) ?
  • ????{ ?
  • ????????ret.data[i]?=?(data[i]?+?down?*?(MAXN?+?1))?/?b; ?
  • ????????down?=?data[i]?+?down?*?(MAXN?+?1)?-?ret.data[i]?*?b; ?
  • ????} ?
  • ????ret.len?=?len; ?
  • ????while(ret.data[ret.len?-?1]?==?0)?ret.len--; ?
  • ????return?ret; ?
  • } ?
  • void?BigInteger::print() ?
  • { ?
  • ????int?i; ?
  • ?
  • ????cout?<<?data[len?-?1]; ?
  • ????for(i?=?len?-?2?;?i?>=?0?;?i--) ?
  • ????{ ?
  • ????????cout.width(GROUP_LEN); ?
  • ????????cout.fill('0'); ?
  • ????????cout?<<?data[i]; ?
  • ????} ?
  • ????cout?<<?endl; ?
  • } ?
  • int?main() ?
  • {?? ?
  • ????clock_t???start,???finish;??? ?
  • ????double?????duration;??? ?
  • ????int?i,n; ?
  • ????BigInteger?result,num; ?
  • ????scanf("%d",&n); ?
  • ????start???=???clock();???? ?
  • ????result?=?BigInteger(1); ?
  • ????for(i?=?2;i?<=?n;?++i) ?
  • ????{ ?
  • ????????num?=?BigInteger(i); ?
  • ????????resultresult?=?result?*?num; ?
  • ????} ?
  • ????result.print(); ?
  • ????finish???=???clock();??? ?
  • ????duration???=???(double)(finish???-???start)???/???CLOCKS_PER_SEC;?? ?
  • ????printf(???"%f???seconds\n",???duration???);??? ?
  • ????return?0; ?
  • }?
  • 下面給出測試結(jié)果,

  • 我的機器配置:酷睿雙核2.0G,內(nèi)存3G, ?
  • 計算10000的階乘,我的機器用時3.312秒,在HDU的服務(wù)器上,10000的階乘用時不到900毫秒。 ?
  • 計算12345的階乘,我的機器用時5.078秒。 ?
  • 計算20000的階乘,我的機器用時13.656秒。?
  • C/C++確實是會快些的,HDU的這道題目對Java程序的時限是5秒內(nèi)完成1萬的階乘,但c/c++的時限是1秒,由此可以看出。

    大家也可以試試在HDU的服務(wù)器上提交下你的代碼,看看能否在1秒內(nèi)通過。

    此外,還有2個常見的N!題目,就是N!的尾數(shù)0的個數(shù)和N!的非零末尾數(shù),有興趣的同學可以自己看看。

    轉(zhuǎn)載于:https://blog.51cto.com/phinecos/368956

    總結(jié)

    以上是生活随笔為你收集整理的回《笔试常见的“阶乘”编程题,你写对了么?》的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。