洛谷: P2404 自然数的拆分问题

原题地址:P2404 自然数的拆分问题 - 洛谷

题目描述

任何一个大于 1 的自然数 n,总可以拆分成若干个小于 n 的自然数之和。现在给你一个自然数 n,要求你求出 n 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

输入格式

输入:待拆分的自然数 n。

输出格式

输出:若干数的加法式子。

输入输出样例

输入 #1复制

7

输出 #1复制

1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4

        该题是一道非常经典的dfs回溯题,其中最主要的难点就是要保证每个拆分的式子的唯一性。比如当n等于7时,1 + 1 + 1 + 2 + 2和1 + 1 + 2 + 1 + 2是一样的只能输出字典序更小的那一个。可以定义一个数组a来记录每次拆分的数,t表示拆分出第t个数。每次循环都从a[t - 1]开始,就可以有效地避免上面那种情况,可以保证第t个数要大于等于前面的数,然后再循环内部进行递归回溯.

具体代码如下:

#include <iostream>
#include <vector>
using namespace std;

int n;
int a[100] = {1};

void print(int count){
    for (int i = 1;i <= count - 1;++i){
        cout<<a[i]<<"+";
    }
    cout<<a[count]<<endl;
}
void dfs(int s,int t){//s表示要拆分的数,t表示拆分到第几位数
    for (int i = a[t - 1];i <= s;++i){
        if (i < n)
        {
            a[t] = i;
            s -=i;
            if (s == 0)
                print(t);
            else
                dfs(s,t + 1);
            s += i;
        }
    }
}
int main()
{
    cin>>n;
    dfs(n,1);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值