【ACM】组合数 - 全排列
组合数
时间限制:3000 ms | 内存限制:65535 KB
难度:3
- 描述
- 找出从自然数1、2、... 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。
- 输入
- 输入n、r。
- 输出
- 按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。 - 样例输入
-
5 3
- 样例输出
-
543 542 541 532 531 521 432 431 421 321
思路:就是全排列嘛,可以衍生为八皇后问题
#include <iostream> #include <cmath> #include <cstdio> using namespace std; int count = 0; int sum = 1; bool rule(int *a, int num){ for (int i = 1 ; i < num ; i++) { if (a[i-1]<a[i]) { return false; } } return true; } void AllLine(int *a, int n, int k, int num){ if (k==n-1) { if (count % sum==0 && rule(a,num)) { int i; for (i = 0; i < num-1 ; i++) { cout<<a[i]; } cout<<a[i]<<endl; } count++; return; } else { for (int z = k ; z < n ; z++) { swap(a[z],a[k]); AllLine(a,n,k+1,num); swap(a[z],a[k]); } } } int main(){ int n,num; while(scanf("%d%d",&n,&num)!=EOF){ for (int k = 1 ; k <= n-num ; k++) { sum *= k; } int *a = new int[n]; for (int i = 0 ; i < n ; i++) { a[i] = n-i; } AllLine(a,n,0,num); } return 0; }
全排列基本模型(注:根据题型,可以将 int 数组换成 char 等):
#include <iostream> #include <cmath> using namespace std; void foo(int n,int k,int *a){ if(k==n-1) { for(int i = 0;i<n;i++){ cout<<a[i]<<" "; } cout<<endl; return; }else{ for(int j = k; j < n; j++){ int temp=a[k]; a[k]=a[j]; a[j]=temp; foo(n,k+1,a); temp=a[k]; a[k]=a[j]; a[j]=temp; } } } int main() { int n=4; int *a = new int[n]; for(int i=0;i<n;i++){ a[i]=i+1; } for(int i=0;i<n;i++){ cout<<a[i]<<" "; } cout<<endl; cout<<"begin"<<endl; foo(n,0,a); cout<<"end"<<endl; return 0; }
输出:
1 2 3 4 begin 1 2 3 4 1 2 4 3 1 3 2 4 1 3 4 2 1 4 3 2 1 4 2 3 2 1 3 4 2 1 4 3 2 3 1 4 2 3 4 1 2 4 3 1 2 4 1 3 3 2 1 4 3 2 4 1 3 1 2 4 3 1 4 2 3 4 1 2 3 4 2 1 4 2 3 1 4 2 1 3 4 3 2 1 4 3 1 2 4 1 3 2 4 1 2 3 end