整数划分问题(c)

将正整数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;
}

         谢谢浏览,如果对你有用点个赞呗     

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值