题目描述
1059 Prime Factors (25分)
Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format
N
=
p
1
k
1
×
p
2
k
2
×
…
×
p
m
k
m
N = p_1^{k1}\times p_2^{k2}\times …\times p_m^{k_m}
N=p1k1×p2k2×…×pmkm
Input Specification:
Each input file contains one test case which gives a positive integer N in the range of long int.
Output Specification:
Factor N in the format
N
=
p
1
k
1
×
p
2
k
2
×
…
×
p
m
k
m
N = p_1^{k1}\times p_2^{k2}\times …\times p_m^{k_m}
N=p1k1×p2k2×…×pmkm, where pi’s are prime factors of N in increasing order, and the exponent
k
i
k_i
ki is the number of
p
i
p_i
pi – hence when there is only one
p
i
p_i
pi,
k
i
k_i
ki is 1 and must NOT be printed out.
Sample Input:
97532468
Sample Output:
97532468=2^2*11*17*101*1291
求解思路
题意:给出一个int范围的整数,按照从小到大的顺序输出其分解为质因数的乘法算式。
思路:先把素数表打印出来,然后再进行质因子分解的操作。
打印素数表:定义一个数组用以保存100010内的素数。
质因子分解:
- 定义一个结构体factor用以保存质因子及其个数。考虑到 2 × 3 × 5 × 7 × 11 × 13 × 17 × 19 × 23 × 29 2\times 3\times 5\times 7\times 11\times 13\times 17\times 19\times 23\times 29 2×3×5×7×11×13×17×19×23×29就已经超过了int范围,因此结构体数组长度开到10即可。
- 对于一个正整数n来说,如果它存在1和本身之外的因子,那么一定是在sqrt(n)的左右成对出现。而这里把这个结论用在“质因子”上面,得到了一个更强化的结论:对一个正整数n来说,如果它存在[2,n]范围内的质因子,那么这些质因子全部小于等于sqrt(n),要么只存在一个大于sqrt(n)的质因子,而其余质因子全部小于等于sqrt(n)。这给质因子分解提供了一个很好的思路:
- 枚举1~sqrt(n)范围内的所有质因子p,判断p是否是n的因子;
- 如果p是n的因子,那么给fac数组中增加质因子p,并初始化其个数为0。只要p还是n的因子,就让n不断除以p,每次都让p的个数++,直到p不再是n的因子为止。
- 如果不是,直接跳过
- 如果在上面步骤结束后n仍然大于1,说明n有且仅有一个大于sqrt(n)的质因子(有可能是n本身),这是就需要把这个质因子加入fac数组并令其个数为1。
- 至此,fac数组中存放的就是质因子分解的结果,时间复杂度为 O ( n ) O\left(\sqrt n\right) O(n)
代码实现(AC)
#include<cstdio>
#include<cmath>
const int maxn=100010;
int Primes[maxn],pNum=0; //分别用于保存素数,素数的个数
struct factor{
int x; //用于存储质因子
int cnt; //用于存储质因子的个数
}fac[10];
/*判断是否是质数*/
bool isPrime(int n)
{
if(n==1) return false;
else
{
for(int i=2;i<=(int)sqrt(n);i++)
{
if(n%i==0) return false;
}
return true;
}
}
/*打印素数表*/
void find_Primes()
{
for(int i=1;i<maxn;i++)
{
if(isPrime(i)) Primes[pNum++]=i;
}
}
/*质因子分解操作*/
void solve()
{
find_Primes();
int n,num=0; //n为待分解的数,num为n质因子的个数
//printf("%d\n",Primes[0]);
scanf("%d",&n);
if(n==1) printf("1=1"); //1是特殊情况
else
{
printf("%d=",n);
/*枚举根号n内的质因子*/
int sqrt_n=(int)sqrt(n);
for(int i=0;i<pNum&&Primes[i]<=sqrt_n;i++)
{
if(n%Primes[i]==0)
{
/*如果i是n的质因子,则将其添加到fac数组中并让其个数为0*/
fac[num].x=Primes[i];
fac[num].cnt=0;
/*计算质因子Primes[i]的个数*/
while(n%Primes[i]==0)
{
fac[num].cnt++;
n/=Primes[i];
}
num++;
}
if(n==1) break; //及时退出循环
}
if(n!=1)
{
/*如果无法被根号n内的质因子除尽,那么一定有一个大于根号n的质因子*/
fac[num].x=n;
fac[num].cnt=1;
num++;
}
/*输出结果*/
for(int i=0;i<num;i++)
{
if(i>0) printf("*");
printf("%d",fac[i].x);
if(fac[i].cnt>1) printf("^%d",fac[i].cnt);
}
}
}
int main()
{
solve();
return 0;
}