7-37 整数分解为若干项之和

将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,…。编程求出正整数N的所有整数分解式子。

输入格式:

每个输入包含一个测试用例,即正整数N (0<N≤30)。

输出格式:

按递增顺序输出N的所有整数分解式子。递增顺序是指:对于两个分解序列N​1​​={n​1​​,n​2​​,⋯}和N​2​​={m​1​​,m​2​​,⋯},若存在i使得n​1​​=m​1​​,⋯,n​i​​=m​i​​,但是n​i+1​​<m​i+1​​,则N​1​​序列必定在N​2​​序列之前输出。每个式子由小到大相加,式子间用分号隔开,且每输出4个式子后换行。

输入样例:

7

输出样例:

7=1+1+1+1+1+1+1;7=1+1+1+1+1+2;7=1+1+1+1+3;7=1+1+1+2+2
7=1+1+1+4;7=1+1+2+3;7=1+1+5;7=1+2+2+2
7=1+2+4;7=1+3+3;7=1+6;7=2+2+3
7=2+5;7=3+4;7=7

看到这个题的通过率,本来以为这道题会是很简单的,结果读完题目我就觉得一点儿都不像想象中那么简单好吧!其实这道题蛮坑的,很多要求都要自己总结出来。比如每行最后一个式子都没有分号,式子到底是怎么排列的。

首先自己应该找到规律,每个分解式之间要按递增的规律输出,即后一项要大于等于前一项。如果目前所有项的总和小于N,则改变下一项的大小;如果等于N,则输出;如果大于N, 则返回。做了挺久的,思路也转换到递归和全局数组上去了。(这是别人的思路,不过跟我的想法大同小异)上一次写递归,除了最近写的求最大公约数,大概是很久以前写的八皇后问题了吧,感觉一点都不会写了。下面是我写的代码,在网上比较了一番,感觉我写的还是太麻烦了。不过还是厚脸皮贴在下面吧!

#include<iostream>

using namespace std;

void ChangeArray(int m, int left);

int num[30];
int N, cnt = 0, k;	//cnt:输出的表达式数量, 用于控制输出换行符 k:当前控制分解式的第几个数

int main(){	
	int i;
	cin >> N;
	for(i = 0; i < N; i++)
		num[i] = 1;
	k = N - 1;
	cout << N << '=';
	for(i = 0; i < N; i++){
		if(i != N - 1) cout << "1+";
		else{
			cout << "1";
			if(num[0] != N) cout << ';';	
		}
	}
	cnt++;
	while(k >= 0){	
		ChangeArray(k, N - k);
		k--;
	}
}

void ChangeArray(int k, int left){
	//改变数组k位及k位以后
	int i, j, max;
	if(k != 0){
		max = num[k - 1] > 2 ? num[k - 1] : 2;
		for(i = max; i <= left; i++){
			num[k] = i;
			ChangeArray(k + 1, left - i);
		}
	}else{
		for(i = 2; i <= left; i++){
			num[k] = i;
			ChangeArray(k + 1, left - i);
		}
	}
	//输出
	if(left == 0){
		cnt++;
		cout << N << '=';
		for(i = 0; i < k; i++){
			if(i != k - 1) cout << num[i] << '+';
			else cout << num[i];
		}
		if(num[0] != N){
			if(cnt % 4 == 0 ) cout << '\n';
			else cout << ';';
		}
	}
	//返回
	return ;
}

猜你喜欢

转载自blog.csdn.net/LightInDarkness/article/details/81544536