P2404 自然数的拆分问题c++题解

    科技2022-08-19  119

    P2404 自然数的拆分问题

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

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

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

    输入输出样例 输入 7 输出 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

    这就是一个简单的求各个数求和,问满足条件的式子有多少个? 道理大家都懂,但是怎么用代码来实现呢,首先我们观察样例可以看到拆分的自然数总是大于或者等前一位数,所以我们要定义一个变量来存储前一个数的信息,避免重复寻找相同的式子, 当然我们需要知道当前式子之和为多少 以及我们要操作的数是第几位 并用一个数组存储这若干个自然数

    void backtrack(int n, int sum, int i, int b[], int qs); //n为要拆分的数 //sum为式子数的总和 //i为当前操作是第i位数 //b为该若干个数 //qs前一个数的值

    然后在进行递归就行了,在递归的时候我们是从qs开始一直到n-1进行循环的,如果超出了n的值就退出递归。

    #include<bits/stdc++.h> using namespace std; void backtrack(int n, int sum, int i, int b[], int qs) { if(n == sum) { //两个值相等表示找到了一个这样的式子 for(int j = 1; j <= i-2; j++) { cout << b[j] << "+"; } cout << b[i-1] <<endl; return ; } if(i > n+1) return ; //超出了值退出递归 for(int j = qs; j <= n-1; j++) { b[i] = j; backtrack(n, sum+j, i+1, b, j); b[i] = 0; } } int main() { int n; int b[10]; cin >> n; memset(b, 0, sizeof(b)); backtrack(n, 0, 1, b, 1); }
    Processed: 0.016, SQL: 9