sicily1000. 整数划分
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前面
注意输出没有空格
Sample Input
Copy sample input to clipboard
1
5
Sample Output
5
4+1
3+2
3+1+1
2+2+1
2+1+1+1
1+1+1+1+1
解题思路:
1、将m看成m个1,其最多划分成m个部分
2、把m划成0个部分,输出m。
把m划分第1个部分, m-1, 1
m-2, 2
m-3, 3
1, m-1
当第一部分小于第二部分, 不进行输出, 继续划分。
当最后部分划分为1,结束划分。
把m划分第2个部分, m-2, 1,1
m-3, 2,1
m-3, 1,2
m-4, 3,1
m-4, 2,2
m-4, 1,3
….
…..
1,1, m-2
当第i(i>=1)部分小于i-1部分, 不进行输出, 继续划分。
当划分第i(i>=2)部分, 划分时需判断是否小于前一部分,
是,继续划分。
否,结束划分。
#include <cstdio>
#include <cctype>
#include <cstdio>
int list[100001];
void divide(int n, int m) {
if (m == 0 || list[m] <= list[m-1]) {
for (int i = 0; i <= m; i++) {
if (i == 0)
printf("%d", list[0]);
else
printf("+%d", list[i]);
}
printf("\n");
}
for (int i = n-1; i >= 1; i--) {
list[m] = i;
list[m+1] = n-i;
if (m == 0 || list[m] <= list[m-1]) {
divide(n-i, m+1);
}
}
}
int main() {
int n, m;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &m);
list[0] = m;
divide(m, 0);
}
return 0;
}