求和(1,2,3.....n使其和为m的所有情况)

输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 
输入描述:
每个测试输入包含2个整数,n和m


输出描述:
按每个组合的字典序排列输出,每行输出一种组合
示例1

输入

5 5

输出

1 4

2 3

5

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

vector<int> v;
void find_ans(vector<int> ret, int cur_pos, int n, int cur_sum, int sum) {
    if (cur_pos >= n) return ;
    cur_sum += v[cur_pos];
    ret.push_back(v[cur_pos]);
    if (cur_sum == sum) {
        for (int i = 0; i < ret.size() - 1; ++i) {
            cout << ret[i] << " ";
        }
        cout << ret[ret.size() - 1];
        cout << endl;
        return ;
    } else if (cur_sum > sum) { // 大于sum,就没必要再继续往下了,剪枝操作
        return ;
    }
    // 把当前的下标位置的值放进去,继续下一个位置
    find_ans(ret, cur_pos+1, n, cur_sum, sum);
    // 不要当前值,从下一个位置搜索,意思大概就是不从1开始找了,从2开始找
    vector<int>::iterator it = ret.end();
    --it;
    ret.erase(it);
    find_ans(ret, cur_pos+1, n, cur_sum - v[cur_pos], sum);
    // 总体思想就是当前位置的数是要还是不要的事情,列出来所有的可能,挨个输出就行了
}
int main() {
    int n, num;
    cin >> n >> num;

    for (int i = 0; i < n; ++i) {
        v.push_back(i+1);
    }
    // 因为如果n大于num的话,那么num后面的数字肯定不需要再考虑了,所以我们只需要考虑从1~num之间的可能组合就行了
    if (n >= num) n = num;

    vector<int> ret;
    int sum = 0;
    // 利用递归的方法来做,0是当前位置,n是最大下标,sum是当前和,num就是要求的结果
    find_ans(ret,0,n,sum,num);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rs勿忘初心

您的鼓励将是我的最大创动原动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值