递归训练:素因子分解(分析子问题)

【问题描述】
给定某个正整数 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;
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40163242/article/details/88069332