C++全排列 和组合

全排列的写法:先确定第一个元素,后面的元素逐渐交换。

#include <iostream>
using namespace std;

void Perm(int start, int end, int a[]){
    //得到全排列的一种情况,输出结果
    if (start == end){
        for (int i = 0; i < end; i++)
            cout << a[i] << ' ';
        cout << endl;
        return;
    }
    for (int i = start; i < end; i++){
        swap(a[start], a[i]);      //交换
        Perm(start + 1, end, a);   //分解为子问题a[start+1,...,end-1]的全排列
        swap(a[i], a[start]);      //回溯
    }
}
int main() {
    int i, n, a[10];
    while (cin >> n, n) {
        for (i = 0; i < n; i++)
        {
            a[i] = i + 1;
        }
        Perm(0, n, a);
    }
    return 0;
}

全排列模板写法:

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

int main()
{
    std::array<int, 3> A = {1,2,3};
    do {
        for (auto i : A)
            cout << i << " ";
        cout << std::endl;
    } while (next_permutation(A.begin(), A.end()));
}

c++  组合:

#include <iostream>
using namespace std;

void dfs(int pos, int cnt, int n, int k, int a[],bool visited[]) {
    //已标记了k个数,输出结果
    if (cnt == k){
        for (int i = 0; i < n; i++)
            if (visited[i]) cout << a[i] << ' ';
        cout << endl;
        return;
    }
    //处理到最后一个数,直接返回
    if (pos == n) return;
    
    //如果a[pos]没有被选中
    if (!visited[pos]) {
        //选中a[pos]
        visited[pos] = true;
        //处理在子串a[pos+1, n-1]中取出k-1个数的子问题
        dfs(pos + 1, cnt + 1, n, k, a,visited);
        //回溯
        visited[pos] = false;   
    }
    //处理在子串a[pos+1, n-1]中取出k个数的问题
    dfs(pos + 1, cnt, n, k, a, visited);
}
int main() {
    int i, n, k;
    while (cin >> n >> k, n || k) 
    {
        int *a = new int[n];
        bool *visited = new bool[n];
        for (i = 0; i < n; i++)
        {
            a[i] = i + 1;
            visited[i] = false;
        }
        dfs(0, 0, n, k, a, visited);
        delete[] a;
        delete[] visited;
    }
  //  getchar();
    return 0;
}

 

 

 

转载:https://segmentfault.com/a/1190000002486075

           https://blog.csdn.net/hf19931101/article/details/79452799

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值