2749:分解因数-POJ

2749:分解因数

总时间限制:1000ms                       内存限制:65536kB

描述

给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * ... * an,并且1 < a1 <= a2 <= a3 <= ... <= an,问这样的分解的种数有多少。注意到a = a也是一种分解。

输入

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a (1 < a < 32768)

输出

n行,每行输出对应一个输入。输出应是一个正整数,指明满足要求的分解的种数

样例输入

2
2
20

样例输出

1
4

i = 2~an,通过an%i ==0来判断i是不是an的因数,如果是,则由an/i作为参数进一步带入函数来判断直至an/i == i,(此时i为最后一个因数)。首先需知道f(m,n)的含义——求n中从m开始到n/m所有分解种数的和。而为什么每次只要满足上面的条件就算一种情况呢?这不妨举个例子当n = 100时,2、50算一种情况,而50可以继续分为2、25,这就有了2、2、25这种情况,再继续分,且每次分都能成为其一种分解情况所以a++。

下面另一种写法,区别在于分解次数加一是在每种分解情况完成时进行的,加的顺序是从分解到的最小因子开始加起,如对n = 100时一次调用f(2, 50) ,然后f(2, 25) ,f(2, 5), f(5, 5) (每次调用到f(x, x),相当于一种情况,后面变成f(x,1)然后直接a++)则先是递归到2 2 5 5 a++ 后,回溯到f(2, 25), 再是f(25, 25)时相当于2 2 25的情况然后a++ ,然后在回溯到f(2, 50) , f(50, 50),a++,这样对i ~ n/i中的分解情况累加。

再对for循环中的循环条件进行分析,他不会出现对两个相同情况2 50 和 50 2重复a++, 当i = 50 时,调用f(50,2) (f(50, 100/2))时会直接不满足条件而退出。而还要设i<=n, 是为了保证在回溯过程中将f(25, 25) 这样的情况给加上。

而这种情况实现方法像上面提到的虽然不计算重复情况,但还是会执行判断,会更耗时。

C++AC代码:

#include<iostream>
using namespace std;
int a;
 
void f(int m, int n) {
    if(n == 1) {
        a++;
        return ;
    }
	else for(int i = m; i <= n; ++i)
		if(n % i == 0){
			f(i, n/i);	
		}
}
 
int main() {
	int n;
	cin >> n;
	while(n--){
		a = 0;
		int x;
		cin >> x;
		f(2, x);
		cout << a << endl;
	}
}

而下面这种实现更是递归最典型的用法,是自顶向下的递归实现思路。从x开始向1递归,对1到x的每位进行判断(是否是其最大因子)累加次数的同时,加上下次递归的f(a, b-1)的情况,f(a, b)中若a%b == 0 则,进一步递归分解。否者对b-1进行判断。b减到1时结束返回0(可以想象一个质数只有第一次加一,后面b一直在减一,直到b == 1则返回0),而被分解的数a等于1,意味着上次调用时的因数刚好将其整除尽,算作一种情况返回1。

#include<iostream>
using namespace std;
 
int count(int a, int b) {
	if(a == 1)//when a == b then a/b == 1 then sum++
		return 1;
	if(b == 1)//border
		return 0;
	if(a % b == 0)
		return count(a/b, b) + count(a, b-1);//use f(a,b-1) to get cycle from n-1 to 2
	else
		count(a, b-1);
}
int main() {
	int n;
	cin >> n;
	while(n--) {
		int x;
		cin >> x;
		cout << count(x, x) << endl;
	}
}


---------------------
作者:会悟
来源:CSDN
原文:https://blog.csdn.net/github_39329077/article/details/83378754
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/www_helloworld_com/article/details/88718390
今日推荐