【问题描述】
给定某个正整数 N,求其素因子分解结果
输入格式:
输入long int范围内的正整数 N。
输出格式:
按给定格式输出N的素因式分解表达式,即 N=p1k1*p2k2*…*pm^km,其中pi为素因子并要求由小到大输出,指数ki为pi的个数;当ki为1即因子pi只有一个时不输出ki。
输入样例:
1323
输出样例:
1323=3^3 * 7^2
【思路】
本题你当然可以用循环暴力去求解,但我不喜欢那样,我觉得从递归的角度思考这一题更加有趣。正如我说的,做递归题关键在于分析它的子问题,每一个递归问题的求解都是建立在子问题被解决的基础之上的,这是核心思想!通过这一题的训练,可以很好的锻炼我们寻找子问题的能力。
题目要求对一个数n进行素因子分解,好,那我就依照题意,设 f( n ) 就表示输出正整数n的素因子分解情况。那么如何分析子问题呢?我们以1323为例,如果你已经会打印49(7 ^ 2)的素因子分解式,那么我们只需要在打印49的分解式之前打印3 ^ 3, 分解1323的任务实际上就完成了!
所以递归式大概就是:f(n) = 打印a^b + f(n / a ^ b) (a是正整数n可以分解出的一个质因数,b是该质因数的幂),a和b也是很好求的。
分析可能看起来有点啰嗦,直接上AC代码:
#include<iostream>
using namespace std;
#define ll long long
ll d;
void f(ll n)
{
ll i = 0;
ll a = 0; //底数
ll p = 0; //幂
for(i = 2;i * i <= d;i++) //从小到大枚举,找出一个可分解的质因数
{
while(n % i == 0) //算该质因数幂的过程
{
a = i;
p++;
n /= i;
}
if(p != 0) //一旦找到就跳出
break;
}
if(p != 0)
{
if(n != 1) //边界在后面 , n == 1 就不继续调用了
{
if(p != 1)
cout << a << "^" << p << "*";
else
cout << a << "*";
f(n); //n已经自我除掉了一部分,递归打印剩余部分就可以
}
else //n == 1
{
if(p != 1)
cout << a << "^" << p; //直接输出就行了
else
cout << a;
}
}
else //如果找不到质因数来分解,直接输出自己
{
cout << n;
}
}
int main()
{
ll n;
cin >> n;
cout << n << "=";
d = n;
f(n);
return 0;
}
运行结果: