南阳OJ 题目56-阶乘因式分解(一)

来源:互联网 发布:房屋设计软件哪个好 编辑:程序博客网 时间:2024/05/17 01:58

1.题目描述:题目链接

阶乘因式分解(一)

时间限制:3000 ms  |  内存限制:65535 KB
难度:2
描述

给定两个数m,n,其中m是一个素数。

将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m。

输入
第一行是一个整数s(0<s<=100),表示测试数据的组数随后的s行, 每行有两个整数n,m。
输出
输出m的个数。
样例输入
2100 516 2
样例输出
2415

2.解题思路

2.1 方法一:动态规划法

   输入n和m,要求n!中m的个数,n!=n*(n-1)*......*3*2*1.因此将公式展开,从1-n求解m的个数,存在求解的子问题,因此采用动态规划法。

2.2 方法二:超简单

   我这个傻货只想着高级的范式能有效的提高运行效率,却没有直接看出这个问题的求解,超简单。
  题目要求的是n!中m的个数,既在展开式中,能对m整除才能满足条件,有很多数字直接就不能满足了。因此,整个阶乘的展开式中就那么几个满足条件的特殊数字,记为a,b,c...好了,并且他们之间是有关系的:a=n,b=a/m,c=b/m,直到我们的特殊为0为止,而结果正巧是特殊数字的和(除a外)。
  举个例子:
  a=n=100,m=5;b=a/m=20;c=b/m=4;d=c/m=0;
  结果result=b+c+d=24
  

3.运行代码:

自己的编程习惯和算法
package 语言入门;import java.util.Scanner;/* Dragon 2017.7.24 *  阶乘因式分解(一) *  方法一:用动态规划法来求解 *  运行时间199ms */public class Num_56 {public static void main(String[] args) {Scanner in=new Scanner(System.in);//输入数据组int number=in.nextInt();for(int i=0;i<number;i++){//输入n和mint n=in.nextInt();int m=in.nextInt();//求解m的个数并输出int result=ZhiNumber(n,m);System.out.println(result);}}//使用动态规划的方法,求解中m的个数private static int ZhiNumber(int n, int m) {//定义长度为n的数组,用于填表,保存的数字代表m的个数,下标从1开始int[] flag=new int[n+1];//让初始化的值为-1,若为0会有冲突for(int i=1;i<=n;i++)flag[i]=-1;/*  * 接下来就是对flag数组进行填数和统一求和 * 例:flag[3]表示 n!中的因数3中m的个数 *  n!=1*2*3....*n  将因数都分开来填      *///从1-n 开始填数int i=1; int j=1;while(i<=n){j=i;int jCount=0;//当前数字内部的计数/* 单个数字的内部动态规划填数过程: * 数j刚进来,可以判断是否可以整除,不满足条件,flag[j]=0,此时JCount=0 * 数j被整除进来的,也如此判断,不满足条件,flag[j]=JCount,JCount已内部变化 * j满足条件,JCount变化,j整除 */while( j%m==0 ){//去除重复项,有值if(flag[j] !=-1){jCount=jCount+flag[j];break;}//之前未计算过的else{j=j/m;jCount++;}}flag[i]=jCount;//当前的数字求出结果,进行下一个i++;}//统一求flag中的和值过程int count=0;for(int p=1;p<=n;p++)count=count+flag[p];return count;}}
我是分割线~
参考大神后的算法提高,即法二
package 语言入门;import java.util.Scanner;/* *  保留Scanner输入输出,修改算法 *  运行时间61ms */public class my {public static void main(String[] args) {Scanner in=new Scanner(System.in);//输入数据组int number=in.nextInt();for(int i=0;i<number;i++){//输入n和mint n=in.nextInt();int m=in.nextInt();int sum=0;//求解m的个数并输出while(n != 0){  n /= m;sum += n;}System.out.println(sum);}}}


我是分割线~

package 语言入门;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer;/* * 大神4ms的代码 */public class 大神 {public static void main(String[] args) throws IOException{BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));int count = getInt(stdin.readLine());int m,n,sum = 0;for(int i=0;i<count;i++){StringTokenizer st = new StringTokenizer(stdin.readLine());m = getInt(st.nextToken());//100n = getInt(st.nextToken());//5sum = 0;while(m != 0){  m /= n;sum += m;}System.out.println(sum);}}private static int getInt(String str) {return Integer.parseInt(str);}}


原创粉丝点击