阶乘因式分解(一)(参考+思考)
- /*暴力因式分解*/
- #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]);
- }
- }
/*暴力因式分解*/ #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。
- 输入
- 第一行是一个整数s(0<s<=100),表示测试数据的组数
随后的s行, 每行有两个整数n,m。 - 输出
- 输出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;
}