7.2.1 生成1~n的排列
相比之下perm速度更快,但是print_perm似乎更加好理解一些
#include <stdio.h>
#include <iostream>
using namespace std;
int cnt;
template <class Type>
void perm(Type list[], int k, int m)
{
if(k > m)
{
for(int i = 1; i <= m ; i++)
cout << list[i] << " ";
cout << endl;
cnt++;
}
else for(int i = k; i <= m; i++)
{
swap(list[k], list[i]);
perm(list, k+1, m);
swap(list[k], list[i]);
}
}
void print_permutation(int n, int *A, int cur)
{
int i, j;
if(cur == n)
{
for(i = 0; i < n; i++) printf("%d ", A[i]);
printf("\n");
cnt++;
}
else for(i = 1; i <= n; i++)
{
int ok = 1;
for(j = 0; j < cur; j++)
if(A[j] == i) ok = 0;
if(ok)
{
A[cur] = i;
print_permutation(n, A, cur+1);
}
}
}
const int maxn = 10000;
int main()
{
int m;
int a[maxn];
while(~scanf("%d", &m))
{
cnt = 0;
for(int i = 0; i <= m; i++) a[i] = i;
perm(a, 1, m);
printf("%d\n", cnt);
cout << endl << "print-perm: " << endl << endl;
cnt = 0;
for(int i = 0; i <= m; i++) a[i] = i;
print_permutation(m, a, 0);
printf("%d\n", cnt);
}
return 0;
}
7.2.2 生成可重集的排列
生成有重复元素的排列。此时算法设计书上的方法不太好用了。此外,需要注意的是,a要和p相同。
c
#include <stdio.h> #include <iostream> #include <algorithm> #include <string.h> using namespace std; const int maxn = 10000; int cnt; int a[maxn]; void print_permutation(int n, int P[], int A[], int cur) { int i, j; int c1, c2; if(cur == n) { for(i = 0; i < n; i++) printf("%d ", A[i]); printf("\n"); cnt++; } else for(i = 0; i < n; i++) if(!i || P[i] != P[i-1]) { c1 = 0, c2 = 0; for(j = 0; j < cur; j++) if(A[j] == P[i]) c1++; for(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() { freopen("input", "r", stdin); int m; int a[maxn], p[maxn]; memset(a, 0, sizeof(a)); memset(p, 0, sizeof(p)); while(~scanf("%d", &m)) { cnt = 0; for(int i = 0; i < m; i++) scanf("%d", &p[i]); sort(p, p+m); memcpy(a, p, sizeof(p)); print_permutation(m, p, a, 0); printf("\n"); } return 0; }
利用STL生成组合
c
#include <stdio.h> #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); do { for(int i = 0; i < n; i++) printf("%d ", p[i]); printf("\n"); } while(next_permutation(p, p+n)); return 0; }
解答树
此外,在构造递归的过程中,可以构造解答树来简化问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。