/*暴力因式分解*/ #include<cstdio> #include<cstring> #define N 10000 int cnt[N]; bool prime[N]; void Prim() { memset(prime,false,sizeof(prime)); prime[1] = true; int i,j; for(i=2;i<N;i++) { if (!prime[i]) for(j=i*i;j<N;j+=i) prime[j] = true; } } int main() { int t,n,m,i,j,k; Prim(); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); k = j =2; memset(cnt,0,sizeof(cnt)); while(k<=n)//分解阶乘n!,逐次分解每个数 { j = k; i = 2; while(j!=1) //j==1表示分解完毕 { while(j%i==0) { j=j/i; cnt[i]++; } for(i++;i<N;i++) //计算出下一个素数 if (!prime[i])break; } k++; } printf("%d\n",cnt[m]); } }
给定两个数m,n
求m!分解质因数后因子n的个数。
这道题涉及到了大数问题,如果相乘直接求的话会超出数据类型的范围。
下面给出一种效率比较高的算法,我们一步一步来。
m!=1*2*3*……*(m-2)*(m-1)*m
可以表示成所有和n倍数有关的乘积再乘以其他和n没有关系的
=(n*2n*3n*......*kn)*ohter other是不含n因子的数的乘积 因为 kn<=m 而k肯定是最大值 所以k=m/n
=n^k*(1*2*......*k)*other
=n^k*k!*other
从这个表达式中可以提取出k个n,然后按照相同的方法循环下去可以求出k!中因子n的个数。
每次求出n的个数的和就是m!中因子n的总个数。
来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=56
题目描述:
给定两个数m,n,其中m是一个素数。
将n(0<=n<=10000)的阶乘分解质因数,求其中有多少个m。
2 100 5 16 2
24 15
题目分析:
虽然题目中说道求出n的阶乘,n的值可能很大,但是最终结果是让我们求出m作为质因数的时候,m的个数。所以这个问题就简单化了。在这里我给出两个代码,一个我写的,另一个是他们的最优秀代码。
代码:#include<iostream>
using namespace std;
int main()
{
int s;
cin>>s;
while(s--)
{
int n,m;
cin>>n>>m;
int i,j,num=0,k=0;
for(i=m;i<=n;)
{
if(i%m==0)
{
i/=m;k++;num++;
}
else
{
for(j=0;j<k;j++)
i*=m;
i++;
k=0;
}
}
cout<<num<<endl;
}
return 0;
}
/
#include<stdio.h>
int main()
{
int
t;
scanf("%d",&t);
while(t--)
{
int m,n,i,j,s,k;
scanf("%d %d",&m,&n);
for(s=0,i=n;i<=m;i++)
{
k=i;
while(!(k%n))
{k=k/n;
s++;}
}
printf("%d\n",s);
}
return
0;
}
刚开始一直为0 ;while(!(k%n))中(k%n)忘加括号……不能进行循环……
#include<stdio.h>
int main()
{
int
N,m,n,sum;
scanf("%d",&N);
while(N--)
{
sum =
0;
scanf("%d%d",&m,&n);
while(m)
{
sum = sum +
m/n;
m =
m/n;
}
printf("%d\n",sum);
}
return 0;
}
阶乘因式分解(一)(参考+思考),布布扣,bubuko.com
原文:http://www.cnblogs.com/dreamgoing/p/3578852.html