您的位置:首页 > 其它

算法篇——因子和阶乘

2015-08-30 22:03 281 查看
  来源:《算法竞赛入门经典》例题5.4.2

  题目:输入正整数n(2≤n≤100),把阶乘n!=1*2*3*...*n分解成素因子相乘的形式,从小到大输出各个素数(2、3、5...)的指数。例如,5! 表示为 3 1 1(5!=23*31*51=120),程序忽略比最大素因子更大的素数(否则末尾会有无穷多个0)

  样例输入
  5
  53
  样例输出:
  5! = 3 1 1
  53! = 49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1

  分析:
  注意到n<=100,所以素因子也一定不会超过100(可以用反证法证明如果存在大于100的素因子,这个素因子在等式上无法消去,等式不成立)。

  我们首先构造一张素数表,然后用阶乘的每个因子(从小到大)与素数表中的素数取模,能整除就证明该素数是素因子,并记录每一个素数的指数。因为am * an = am+n,所以我们需要把素因子对应的指数做累加 。用一个数组p来保存对应的各个素数的指数,并标记最大的那个素因子的下标为maxp,最后循环输出到最大素因子的指数即可。

  源码

#include<stdio.h>
#include<string.h>

int is_prime(int n)
{
int i;
for(i=2;i*i<=n;i++)
if(n%i==0)    return 0;
return 1;
}

int main()
{
int n,m,i,j,prime[100],p[100],maxp,count=0;//primer为素数表,p为素数表中各个素数对应的指数
//count为素数表中素数的数量,maxp为最后可以输出的最大素因子对应于p的下标

for(i=2;i<=100;i++)                        //构造素数素数表,素数因子一定不超过100
if(is_prime(i))    prime[count++]=i;
while(scanf("%d",&n)==1)
{
printf("%d! =",n);
memset(p,0,sizeof(p));                 //各素数对应的指数置0
maxp=0;                                //最大素因子索引置0
for(i=1;i<=n;i++)
{
m=i;                               //阶乘的每个因子都循环除以(取模)素数表中的素数
for(j=0;j<count;j++)
while (m%prime[j]==0)          //能整除证明是素因子
{
m/=prime[j];
p[j]++;                    //因子指数加1
if(j>maxp)    maxp=j;      //更新最大素因子下标
}
}
for(i=0;i<=maxp;i++)                   //忽略比最大素因子更大的素数
printf(" %d",p[i]);
printf("\n");

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: