【组合问题】-分解因数

OpenJudge - 1751:分解因数


解题思路:

(1)一个正整数a,分解成若干个正整数的乘积,这几个正整数最小为2,并且是依次递增的。要求共有多少种拆解方案。

(2)那么思路是,将一个整数先除以2,如果能被整除,那么已经有了第一种方案,再看商是否能被2整除,如果可以,继续除2,有了第二种方案,依次累除,当2无法再整除的时候,便尝试3是否可以整除,如果可以,按照同样的思路继续除下去

(3)在除的过程中,什么时候就不应该除下去了呢?首先,如果一直除2的话,最后的商无法再被2整除的时候,返回。还有一点,当商除以2再次得到的商如果小于2了,也不能在除了,因为得到的结果是要形成拆解方案的,最后一个因子只能大于等于前一个因子(仔细理解)

(4)结合下列对36的拆解,体会步骤3

(5)由上图,可以理解到当最右边的分支除到3的时候,最后结果为3,此时不能再除,即使3能被3整除,结果为1,但是形成的方案为36=2*2*3*3*1,很明显不符合拆解要求,同理36=2*3*6的时候也不能再除下去,因为形成的方案为36=2*3*3*2。

(6)那除到什么时候,就可以停了呢,通过上图,思考为什么不枚举到6以后的因数呢?因为9虽然是36的因数,但是因数是一对一对出现的,在4的时候就已经有39=4*9的方案,而且是因数从小到大的,9的时候已经不符合拆解要求了。

(7)很明显,每一个数都在试着去除上一个因数,如果不可行了,便会返回上一层再去试一下能不能除更大的数,符合深度优先搜索的遍历思想,所以利用深搜来实现。


#include<bits/stdc++.h>
using namespace std;
int n,x,cnt;

//start表示开始除的最小因数,num表示被分解的数字 
void dfs(int start,int num)
{
	if(start>num)//如果除数大于被除数了,返回 
	return ;
	
	for(int i=start;i<=sqrt(num);i++)//从start开始试除,到根号num结束 
	{
		if(num%i==0)//可行性方案:如果当前i能被num整除 
		{
			cnt++;//方案数加1 
			dfs(i,num/i);//继续深搜 
		}
	}
}
int main()
{
	cin>>n;//表示求n个数的拆解方案 
	for(int i=1;i<=n;i++)
	{
		cin>>x;//表示要拆解的数
		dfs(2,x);//深度优先搜索 
		
		cout<<cnt+1<<endl;//因为本身也算一种方案 
		cnt=0; //计数器归零 
	}
	return 0;
}

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值