入门经典II 第七章暴力求解法 7.2枚举排列

来源:互联网 发布:mac子弹头真假 编辑:程序博客网 时间:2024/05/17 03:07

说明:按着书中的思想敲的,记录一下自己的学习过程,最下面附带刘汝佳源代码。


1)生成1~n的排列(自己写的)

#include<stdio.h>#include<iostream>using namespace std;int n;void 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=1;i<=n;i++){        int ok=1;        for(int j=0;j<cur;j++)            if(a[j]==i) {ok=0;break;}        if(ok){            a[cur]=i;            p(a,cur+1);        }    }    }}int main(){    int a[1010];    while(cin >>n){        p(a,0);    }    return 0;}

2)生成可重集的排列(自己写的)

#include<stdio.h>int n;void q(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[j]==p[i]) c2++;        if(c1<c2){            a[cur]=p[i];            q(p,a,cur+1);        }    }}int main(){    while(~scanf("%d",&n)){        int p[1010],a[1010];        for(int i=0;i<n;i++)            scanf("%d",&p[i]);        q(p,a,0);    }    return 0;}

3)7.2.4下一个排列(自己敲的)

#include<iostream>#include<stdio.h>#include<algorithm>using namespace std;int main(){    int p[1010],n;    while(cin>>n){        for(int i=0;i<n;i++){            cin >> p[i];        }        sort(p,p+n);        do{            for(int i=0;i<n;i++)                printf("%d ",p[i]);            cout <<endl;        }while(next_permutation(p,p+n));    }    return 0;}


下面是从官网下载的刘汝佳源代码:

// 求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;}


0 0
原创粉丝点击