枚举排列(入门经典7-2)

来源:互联网 发布:淘宝详情页图片上传 编辑:程序博客网 时间:2024/06/13 07:33

枚举排列的常见方法有两种:一是递归枚举,二是STL中的next_permutation.

// 求1~n的全排列. n<100// Rujia Liu#include<cstdio>using namespace std;int A[101];// 输出1~n的全排列void print_permutation(int n, int* A, int cur) {  if(cur == n) { // 递归边界    for(int i = 0; i < n; i++) printf("%d ", A[i]);    printf("\n");  } else for(int i = 1; i <= n; i++) { // 尝试在A[cur]中填各种整数i    int ok = 1;    for(int j = 0; j < cur; j++)      if(A[j] == i) ok = 0; // 如果i已经在A[0]~A[cur-1]出现过,则不能再选    if(ok) {      A[cur] = i;      print_permutation(n, A, cur+1); // 递归调用    }  }}int main() {  int n;  scanf("%d", &n);  print_permutation(n, A, 0);   return 0;}

// 可重集的全排列// Rujia Liu#include<cstdio>#include<algorithm>using namespace std;int P[100], A[100];// 输出数组P中元素的全排列。数组P中可能有重复元素void print_permutation(int n, int* P, int* A, int cur) {  if(cur == n) {    for(int i = 0; i < n; i++) printf("%d ", A[i]);    printf("\n");  } else for(int i = 0; i < n; i++) if(!i || P[i] != P[i-1]) {    int c1 = 0, c2 = 0;    for(int j = 0; j < cur; j++) if(A[j] == P[i]) c1++;    for(int j = 0; j < n; j++) if(P[i] == P[j]) c2++;    if(c1 < c2) {      A[cur] = P[i];      print_permutation(n, P, A, cur+1);    }  }}int main() {  int i, n;  scanf("%d", &n);  for(i = 0; i < n; i++)    scanf("%d", &P[i]);  sort(P, P+n);  print_permutation(n, P, A, 0);  return 0;}

// 可重集的全排列(next_permutation版)// Rujia Liu#include<cstdio>#include<algorithm>using namespace std;int main() {  int n, p[10];  scanf("%d", &n);  for(int i = 0; i < n; i++) scanf("%d", &p[i]);  sort(p, p+n); // 排序,得到p的最小排列  do {    for(int i = 0; i < n; i++) printf("%d ", p[i]); // 输出排列p    printf("\n");  } while(next_permutation(p, p+n)); // 求下一个排列  return 0;}

前面两个代码比较朴实,最后一个用到了STL很方便。

前面两个比较难记。。最后一个next_permutation只需要记住这一个函数就可以了。。自动排列好,直到没有下一个排列

next_permutation
next_permutation

阅读全文
0 0
原创粉丝点击