输出整数的所有划分

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 
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);
    }
}


你可能感兴趣的:(数据结构与算法)