一.产生类循环排列
输入样例
3 2
输出样例
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
输入样例
3 2
输出样例
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
#include <iostream>
#include <ctime>
using namespace std ;
int A[100] ;
void Print_permutation(int n, int *A , int cur) {
int i , j ;
if (cur == n) {
/*for (i = 0 ; i < n ; ++ i) {
cout << A[i] << " " ;
}
cout << endl ; */
}
else {
for (i = 1 ; i <= n ; i ++) {
bool flag = true ;
for (j = 0 ; j < cur ; ++ j) {
if (A[j] == i) {
flag = false ;
break ;
}
}
if (flag) {
A[cur] = i ;
Print_permutation(n,A,cur+1) ;
}
}
}
}
int main() {
int n = 0 ;
clock_t start , end ;
cin >> n ;
start = clock() ;
Print_permutation(n,A,0) ;
end = clock() ;
cout << endl << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl ;
return 0 ;
}
实际上,这样的方法是用递归实现多重循环,本递归程序相当于n 重循环,每
重循环的长度为m 的情况,所以输出共有m^n 行。
二.不重复排列:
输入n 个数,输出由这n 个数构成的排列,不允许出现重复的项。
输入样例
3
1 1 2
输出样例
1 1 2
1 2 1
2 1 1
Version One :
LRJ代码:
#include <iostream>
using namespace std ;
int P[100] , A[100] ;
void Print_permutation(int n , int *P , int *A , int cur) {
if (cur == n) {
for (int i = 0 ; i < n ; ++ i) {
cout << A[i] << " " ;
}
cout << endl ;
}
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 n ;
cin >> n ;
for (int i = 0 ; i < n ; ++ i) {
cin >> P[i] ;
}
Print_permutation(n,P,A,0) ;
return 0 ;
}
Version Two :
#include <iostream>
using namespace std ;
const int MAXN = 100 ;
int A[MAXN] , P[MAXN] , used[MAXN] , tmp[MAXN] ;
void Print_permutation(int n , int m , int *A , int *P , int cur) {
if (cur == n) {
for (int i = 0 ; i < n ; ++ i) {
cout << A[i] << " " ;
}
cout << endl ;
}
else {
for (int i = 0 ; i < m ; ++ i) {
if (used[i] > -1) {
used[i] -- ;
A[cur] = P[i] ;
Print_permutation(n,m,A,P,cur+1) ;
used[i] ++ ;
}
}
}
}
int main() {
int n , m ;
cin >> n ;
int count = 0 ;
memset(P,0,sizeof(P)) ;
for (int i = 0 ; i < n ; ++ i) {
cin >> tmp[i] ;
P[count++] = tmp[i] ;
for (int j = 0 ; j < i ; ++ j) {
if (tmp[j] == tmp[i]) {
used[j] ++ ;
count -- ;
break ;
}
}
}
for (int i = 0 ; i < count ; ++ i) {
cout << P[i] << " " ;
}
cout << endl ;
Print_permutation(n,count,A,P,0) ;
return 0 ;
}
(STL 中 next_permutation 方法实现核心)
template<class _BidIt> inline
bool next_permutation(_BidIt _First, _BidIt _Last)
{ // permute and test for pure ascending, using operator<
_DEBUG_RANGE(_First, _Last);
return (_Next_permutation(_Unchecked(_First), _Unchecked(_Last)));
}
template<class _BidIt> inline
bool _Next_permutation(_BidIt _First, _BidIt _Last)
{ // permute and test for pure ascending, using operator<
_BidIt _Next = _Last;
if (_First == _Last || _First == --_Next)
return (false);
for (; ; )
{ // find rightmost element smaller than successor
_BidIt _Next1 = _Next;
if (_DEBUG_LT(*--_Next, *_Next1))
{ // swap with rightmost element that's smaller, flip suffix
_BidIt _Mid = _Last;
for (; !_DEBUG_LT(*_Next, *--_Mid); )
;
_STD iter_swap(_Next, _Mid);
_STD reverse(_Next1, _Last);
return (true);
}
if (_Next == _First)
{ // pure descending, flip all
_STD reverse(_First, _Last);
return (false);
}
}
}
三.全排列:(没有重复元素的输入)
#include <iostream>
using namespace std ;
const int MAXN = 100 ;
int used[MAXN] , A[MAXN] , P[MAXN] ;
void Print_permutation(int n , int *A , int *P , int cur) {
if (cur == n) {
for (int i = 0 ; i < n ; ++ i) {
cout << A[i] << " " ;
}
cout << endl ;
}
else {
for (int i = 0 ; i < n ; ++ i) {
if (!used[i]) {
used[i] = 1 ;
A[cur] = P[i] ;
Print_permutation(n,A,P,cur+1) ;
used[i] = 0 ;
}
}
}
}
int main() {
int n = 0 ;
cin >> n ;
for (int i = 0 ; i < n ; ++ i) {
cin >> P[i] ;
}
memset(used,0,sizeof(used)) ;
Print_permutation(n,A,P,0) ;
return 0 ;
}