您的位置:首页 > 其它

算法竞赛入门经典:第五章 基础题目选解 5.10 因子和阶乘

2015-08-17 12:15 375 查看
/*
因子和阶乘:
输入正整数n(2<=2<=100),把阶乘n!=1*2*3*...*n分解成素因子相乘的形式,从小到大输出各个素数(2,3,5...)的指数。例如825=23*5^2*11应表示成(0,1,2,0,1),
表示分别有0、1、2、0、1个2、3、5、7、11.你的程序应忽略比最大素因子更大的素数(否则末尾会有无穷个0)
输入:
5
53
输出:
5! = 3 1 1
53! = 49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1
关键:
采用分解法,每次用原数除以质数,除以的质数(用素数筛选法标记,预处理)。除以同一个数,素因子累加,除以不同的数,重新开辟一个计数器
*/

/*
关键:
1 素数筛选法:for(int j = i*i; j < MAXSIZE;j += i)//如果用i*k(k<i)那么刚开始i*k必定作为k的第i倍被标记过了
2 for(int m = 1;m <= n; m++)//用阶乘的每一个数去尝试从小到大除以每一个素数
      	for(int k = 2 ; k < MAXSIZE ; k++)
		{
			if(!iMark[k])
			{
				while(0==iRec%k)
3 int iIndex[MAXSIZE] = {0};//用做存放指数次数的数组,一定要初始化
*/

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

#define MAXSIZE 1024

void divideEle(int n)
{
	//预处理,用素数筛选法
	int iMark[MAXSIZE];
	memset(iMark,0,sizeof(iMark));
	for(int i = 2;i < MAXSIZE; i++)
	{
		if(0 == iMark[i])
		{
			for(int j = i*i; j < MAXSIZE;j += i)//如果用i*k(k<i)那么刚开始i*k必定作为k的第i倍被标记过了
			{
				iMark[j] = 1;
			}
		}
	}
	int iIndex[MAXSIZE] = {0};//用做存放指数次数的数组,一定要初始化
	int iMaxPri = 0;//记录最大的质数
	for(int m = 1;m <= n; m++)//用阶乘的每一个数去尝试从小到大除以每一个素数
	{
		int iRec = m;
		for(int k = 2 ; k < MAXSIZE ; k++)
		{
			if(!iMark[k])
			{
				while(0==iRec%k)
				{
					iIndex[k]++;
					iRec /= k;
					if(k > iMaxPri)
					{
						iMaxPri = k;
					}
				}
			}
		}
	}
	printf("%d! = ",n);
	for(int q = 2 ; q <= iMaxPri;q++)
	{
		if(!iMark[q])
		{
			printf("%d ",iIndex[q]);
		}
	}
	printf("\n");
}

int main(int argc,char* argv[])
{
	int n;
	while(EOF != scanf("%d",&n))
	{
		divideEle(n);
	}
	system("pause");
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: