将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,
其中n1≥n2≥…≥nk≥1,k≥1。
正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。
例如正整数6有如下11种不同的划分:
6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1。
输入正整数n的值,输出n的划分种类数及具体的划分情况。测试值(n=6,n=7)
当n=6时,则输出:共有11划分,分别为:
6=6;
6=5+1;
.................................
#include <stdio.h>
#include<iostream>
using namespace std;
int p;//检查递归是否完成记录
int count = 0;
int record[100];//记录重复数值
//用于比m小的数n的拆分
void breakup(int n, int m, int i)
{
if (n == p && n != m)
{
//此时递归栈已经退回到某一分支的最上层,置计数器i为0
printf("\n");
i = 0;
}
if (n == 1)
{
//当n为1,意味着只能表示1
printf("1 ");
count++;
return;
}
else if (m == 1)//当m为1,意味着要输出n个1相加
{
for (int i = 0; i < n - 1; i++)
printf("1+");
printf("1 ");
count++;
return;
}
if (n < m)//利用递归进行数值的输出
{
breakup(n, n, i);
}
if (n == m)
{
//当n等于m时,需要输出多一个空格,隔开下一条式子
printf("%d ", n);
count++;
//在递归输出式子之前,将之前记录的数一并输出
for (int j = 0; j < i; j++)
printf("%d+", record[j]);
breakup(n, m - 1, i);
}
if (n > m)
{
//如果n大于m,则使用m作为分解
printf("%d+", m);
//记录m的值并使i自增
record[i++] = m;
//递归输出m的分解式子
breakup(n - m, m, i);
i--;
for (int j = 0; j < i; j++)
printf("%d+", record[j]);
//递归输出另一种情况
breakup(n, m - 1, i);
}
}
int main()
{
int n;
while ( cin >> n)
{
if (n > 0)
{
p = n;
breakup(n, n, 0);
cout << "\n共有" << count <<"划分,分别为以上情况。\n";
count = 0;
}
}
return 0;
}
谢谢浏览,如果对你有用点个赞呗