输出整数的所有划分

输出整数的所有划分

 

Description:

对于一个整数m,m > 0,它可以写成t个整数的和的形式(t>0):m = z1 + z2 + … + zt ,其中zi > 0且为整数(1≤i≤t)

这t个整数就是整数m的一种划分。

比如整数4有以下5种划分:

4

3+1

2+2

2+1+1

1+1+1+1

Input

第一行是一个整数n,代表有n个测试用例

接下来的n行每一行是一个整数m,代表待划分的整数

Output
对于每一个用例,输出它的所有划分,格式如下:

对于一个划分,它按照数字降序排序,比如:4+3+2+1

对于两个划分3+2和3+1+1的排序:3+2排在3+1+1前面,比较顺序从左到右依次比较,第一个数字3是相等的,接下来第二个数字2 > 1,所以3+2排在3+1+1前面

注意输出没有空格


代码:
#include <iostream>
using namespace std;
int record[1000];

void print(int* r, int length) {
for (int i = 0; i < length - 1; i++) {
cout << r[i] << "+";
}
cout << r[length - 1] << endl;
}

/*
n是需要被划分的整数,n划分中最大的数不大于m, r是暂时保留
未划分完结果的数组,length是r数组中元素的个数
*/
void f(int n, int m, int* r, int length) {
/*1没法再被划分,所以可以输出了*/
if (n == 1) {
r[length] = 1;
print(r, length + 1);
}
/*若n划分中每个数都<=1,说明每个数都是1,也可以输出*/
else if (m == 1) {
for (int i = length; i < length + n; i++) {
r[i] = 1;
}
print(r, length + n);
}
/*n划分中每个数都小于等于n,分两种情况,包含n和不包含n,包含n直接输出n即可,不包含n就相当于n划分中每个数都小于等于n-1,所以递归调用f(n, m - 1,...)*/
else if (n == m) {
r[length] = n;
print(r, length + 1);
f(n, m - 1, r, length);
}
/*由于划分中不能有负数,所以m>n时,等同于m=n*/
else if (n < m) {
f(n, n, r, length);
}
/*也分两种情况:包含m和不包含m,包含m就把一个m作为n划分中新增添的项,然后递归f(n-m, m,...);不包含m就相当于n划分中每个数都小于等于m-1,所以递归调用f(n, m - 1,...)*/
else if (n > m) {
r[length] = m;
f(n - m, m, r, length + 1);
f(n, m - 1, r, length);
}
}


int main(void) {
int n, m;
cin >> n;
while (n--) {
cin >> m;
f(m, m, record, 0);
}
}


————————————————
版权声明:本文为CSDN博主「desirepath」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/desirepath/article/details/50441454

 

posted @ 2023-10-10 17:39  菜鸡一枚  阅读(71)  评论(0编辑  收藏  举报