在做 “容斥原理” 题时经常需要求出一个数的质因子,而且不是所求数的位数很多,就是一次求n多数的质因子。
下面分别给出两种类型的代码,供抛砖引玉。
第一种类型:
用于每次只能求出一个数的质因子,适用于题目中给的n的个数不是很多,但是n又特别大的情况。
#include<stdio.h>
int main()
{
__int64 n;
int i,gs=0;
int p[100];
scanf("%I64d",&n); //输入所要求的数(可能很大,用int64读入)
for(i=2;i*i<=n;i++)
{
if(n%i==0) //若n可以被i整除,则将i加入质因子数组p中
{
p[gs++]=i;
while(n%i==0) //n除尽该质因子i,这样就可以保证下面循环的i一定是质因子
{
n/=i;
}
}
}
if(n>1) //应对“n=103”这种情况
{
p[gs++]=n;
}
for(i=0;i<gs;i++)
{
printf(i+1==gs?"%d\n":"%d ",p[i]);
}
return 0;
}
第二种类型:
求出1~n任意给定数的质因子,适用于题目中给的n比较多,但n不是很大的情况。
想法:将给定1~n范围内所有数的质因子全部求出,存到一个二维数组中(这里使用了c++提供的vector容器,比较方便),最后根据所输入的数输出其的质因子。
如,分别求出0~104所对应的质因子:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector> //必须要包含该头文件
using namespace std;
const int M=105; //用const定义一个常量M
vector<int>p[M]; //创建一个vector对象数组,相当于一个二维数组
int vis[M]; //筛素法中用于标记是否走过
void init()
{
int i,j;
memset(vis,0,sizeof(vis)); //将vis数组初始化为0
for(i=0;i<M;i++) //清空vector数组
{
p[i].clear();
}
for(i=2;i<M;i++) //筛选素数,筛素法
{
if(!vis[i]) //判断是否将i作为质因子
{
for(j=i;j<M;j+=i)
{
p[j].push_back(i); //p[j]具有该质因子i,将i加入p[j]的质因子数组中
vis[j]=1; //j不是素数(质数),在下面的循环中不作为质因子,标记一下
}
}
}
}
int main()
{
int i,j;
init();
for(i=0;i<M;i++)
{
printf("%d的质因子为:",i);
for(j=0;j<(int)p[i].size();j++) //强制类型转换,用p[i].size()可知道p[i]的质因子数组大小(即p[i]有多少个质因子)
{
printf("%d ",p[i][j]); //输出p[i]的质因子
}
printf("\n");
}
return 0;
}