阶乘因式分解(一)(参考+思考)

  1. /*暴力因式分解*/  
  2. #include<cstdio>   
  3. #include<cstring>   
  4. #define N 10000   
  5. int cnt[N];  
  6. bool prime[N];  
  7. void Prim()  
  8. {  
  9.     memset(prime,false,sizeof(prime));  
  10.     prime[1] = true;  
  11.     int i,j;  
  12.     for(i=2;i<N;i++)  
  13.     {  
  14.         if (!prime[i])  
  15.             for(j=i*i;j<N;j+=i)  
  16.                 prime[j] = true;  
  17.     }  
  18. }  
  19.   
  20. int main()  
  21. {  
  22.     int t,n,m,i,j,k;  
  23.     Prim();  
  24.     scanf("%d",&t);  
  25.     while(t--)  
  26.     {  
  27.         scanf("%d%d",&n,&m);  
  28.         k = j =2;  
  29.         memset(cnt,0,sizeof(cnt));  
  30.         while(k<=n)//分解阶乘n!,逐次分解每个数   
  31.         {  
  32.             j = k;  
  33.             i = 2;  
  34.             while(j!=1) //j==1表示分解完毕   
  35.             {   
  36.                 while(j%i==0)  
  37.                 {  
  38.                     j=j/i;  
  39.                     cnt[i]++;  
  40.                 }  
  41.                 for(i++;i<N;i++) //计算出下一个素数   
  42.                     if (!prime[i])break;  
  43.             }  
  44.             k++;  
  45.         }  
  46.         printf("%d\n",cnt[m]);  
  47.     }  
  48. }  
/*暴力因式分解*/
#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<stdio.h>
int main()
{
  int i,j,k,m,n,s;
  scanf("%d",&s);
  while(s--)
  {
  scanf("%d%d",&n,&m);
    for(i=m,j=0;i<=n;i++)
    for(k=i;!(k%m);j++)//j不能写在这里,否则只是n有几个m的个数j。
    k=k/m;
    printf("%d\n",j);
  }
  return 0;
}
 

给定两个数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;
}

posted @ 2014-03-03 17:44  为梦出发  阅读(753)  评论(0编辑  收藏  举报