首页 / 资讯中心 / 文章详情

15:阶乘和

15:阶乘和 ★ FEATURED ARTICLE
/** * 题目名称阶乘和 p * 题目来源http://noi.openjudge.cn/ch0106/15/ p * 程序功能输出指定非负整数的阶乘和 * * author 潘磊just_panleijust.edu.cn * version 1.0 */importjava.util.Arrays;importjava.util.Scanner;publicclassMain{/** * 反转指定数组的指定区间。 * * param nums 指定数组。 * param begin 指定区间的起始边界。 * param end 指定区间的终止边界。 */publicvoidreverse(int[]nums,intbegin,intend){intt;// 暂存变量/* 在区间起始边界小于终止边界时 */while(beginend){// 以下交换左右边界上的两个元素tnums[begin];nums[begin]nums[end];nums[end]t;begin;// 起始边界右移一位end--;// 终止边界左移一位}}/** * 移除指定数组形式的非负整数的前导0。 * * param nums 指定数组形式的非负整数。 * return 移除nums前导0的结果数组。 */publicint[]removeLeadingZeros(int[]nums){intnnums.length;// nums的长度/* 依次遍历nums的每一个元素 */for(inti0;in;i){if(nums[i]!0){// 如果当前元素为非0元素returnArrays.copyOfRange(nums,i,n);// 返回nums下标在[i,n)区间的元素}}returnnewint[]{0};// 以上没有产生返回说明nums所有元素均为0返回数组形式的0}/** * 返回指定非负整数的阶乘。 * * param n 指定非负整数。 * return n的阶乘。 */publicint[]factorial(intn){int[]ansnewint[35660];// n的阶乘最多为35660位ans[0]1;// 计算结果的基数为1intL1;// 计算结果的实际长度初始为1intcarry;// 每次计算的进位/* 从乘数2依次遍历到乘数n */for(inti2;in;i){carry0;// 初始化当前计算的进位为0/* 从当前结果的低位数字依次遍历到高位数字 */for(intj0;jL;j){ans[j]carryans[j]*i;// 当前数位乘以当前乘数同时加上当前进位carry(ans[j]9?ans[j]/10:0);// 更新进位ans[j](ans[j]9?ans[j]%10:ans[j]);// 更新当前数位}/* 在本次乘数计算后产生更高位的进位时注意阶乘计算进位可能会超过10 */while(carry0){ans[L](carry9?carry%10:carry);// 设置更高位的数字L;// 计算结果的实际长度加1carry/10;// 更新进位}}reverse(ans,0,L-1);// 反转ans[0]~ans[L-1]区间returnArrays.copyOfRange(ans,0,L);// ans[0]~ans[L-1]构成最终计算结果}/** * 返回两个指定数组形式的非负整数的和。 * * param numA 指定数组形式的非负整数。 * param numB 指定数组形式的非负整数。 * return 数组形式的numA与numB的和。 */publicint[]add(int[]numA,int[]numB){int[]AremoveLeadingZeros(numA);// 移除numA的前导0int[]BremoveLeadingZeros(numB);// 移除numB的前导0intLAA.length;// A的长度也即numA的有效长度intLBB.length;// B的长度也即numB的有效长度intnMath.max(LA,LB);// 对位加法的次数取决于两个加数中较长的长度int[]ansnewint[n1];// 对位加法的结果可能会多出一位intcarry0;// 每次对位加法产生的进位初始为0reverse(A,0,LA-1);// 从整数低位到高位依次存储A的每位数字reverse(B,0,LB-1);// 从整数低位到高位依次存储B的每位数字/* 从整数低位到高位依次进行对位相加共相加n次 */for(inti0;in;i){// 如果A当前位有数字则用该数字与当前进位相加否则用一个0与当前进位相加ans[i]carry(iLA?A[i]:0);// 如果B当前位有数字则用该数字与上一步的结果相加否则用一个0与上一步的结果相加ans[i](iLB?B[i]:0);if(ans[i]9){// 如果本次对位加法产生新的进位carry1;// 将进位更新为1ans[i]%10;// 当前位的加法结果仅保留个位数字}else{// 否则本次对位加法没有产生新的进位carry0;// 将进位更新为0}}if(carry0){// 如果最后一次对位加法没有产生新的进位reverse(ans,0,n-1);// 反转ans[0]~ans[n-1]区间returnArrays.copyOfRange(ans,0,n);// ans[0]~ans[n-1]构成最终计算结果}ans[n]1;// 此时代表最后一次对位加法产生新的进位必然为1reverse(ans,0,n);// 反转ans[0]~ans[n]区间returnans;// ans[0]~ans[n]构成最终计算结果}/** * 返回阶乘序列1!2!3!…n!的结果。 * * param n 阶乘序列末项的编号。 * return 1!2!3!…n!的和。 */publicint[]sumOfFactorial(intn){int[]ansnewint[65];// 阶乘和的结果最多为65位/* 从数字1依次遍历到数字n */for(inti1;in;i){int[]ffactorial(i);// 计算当前数的阶乘ansadd(ans,f);// 累加当前数的阶乘}returnremoveLeadingZeros(ans);// 返回移除前导0的结果}publicstaticvoidmain(String[]args){MaincallnewMain();ScannerinputnewScanner(System.in);intninput.nextInt();int[]anscall.sumOfFactorial(n);for(inte:ans){System.out.print(e);}}}/** * 题目名称阶乘和 p * 题目来源http://noi.openjudge.cn/ch0106/15/ p * 程序功能输出指定非负整数的阶乘和 * * author 潘磊just_panleijust.edu.cn * version 2.0 */importjava.math.BigDecimal;importjava.util.Scanner;publicclassMain{/** * 返回指定非负整数的阶乘。 * * param n 指定非负整数。 * return n的阶乘。 */publicBigDecimalfactorial(intn){BigDecimalansBigDecimal.ONE;// 初始化阶乘结果为1BigDecimal.ONE常量/* 从乘数2依次遍历到乘数n */for(inti2;in;i){// 调用BigDecimal类的multiply方法完成大整数乘法运算ansans.multiply(BigDecimal.valueOf(i));}returnans;}/** * 返回阶乘序列1!2!3!…n!的结果。 * * param n 阶乘序列末项的序号。 * return 1!2!3!…n!的和。 */publicBigDecimalsumOfFactorial(intn){BigDecimalansBigDecimal.ONE;// 阶乘和的结果初始为1BigDecimal.ONE常量BigDecimalf;// 当前数的阶乘/* 从数字2依次遍历到数字n */for(inti2;in;i){ansans.add(factorial(i));// 累加当前数的阶乘}returnans;}publicstaticvoidmain(String[]args){MaincallnewMain();ScannerinputnewScanner(System.in);intninput.nextInt();BigDecimalanscall.sumOfFactorial(n);System.out.print(ans);}}
阅读完成 · 觉得有帮助?
咨询建站