第一种方法耗费空间比较大,第二种方法更有技巧
方法一:
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
char a[100];
bool vis[100];
int ct[100];
int n;
int cst ;
void dfs(char a[],int i){
if(i == n){
for(int k = 0;k < n;k++)
cout << a[ct[k]] << " ";
cout << endl;
cst ++;
return ;
}
for(int j = 0;j < n;j++){
if(!vis[j]){
vis[j] = 1;
ct[j] = i;
dfs(a,i+1);
vis[j] = 0;
ct[j] = 0;
}
}
}
int main(){
while(cin >> n){
for(int i = 0;i < n;i++)
cin >> a[i];
memset(vis, 0, sizeof(vis));
cst = 0;
dfs(a,0);
cout << cst << endl;
}
system("pause");
}
方法二:
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
#include <algorithm>
char a[100];
int n,cst;
void swap(int &a, int &b){
a = a^b;
b = a^b;
a = a^b;
}
void dfs(char a[],int k,int n){
if(k == n){
for(int p = 0;p < n;p++)
cout << a[p] << " ";
cout << endl;
cst ++;
return ;
}
for(int i = k;i < n;i++){
swap(a[i],a[k]);
dfs(a,k+1,n);
swap(a[i],a[k]);
}
}
int main(){
while(cin >> n){
cst = 0;
for(int i = 0;i < n;i++)
cin >> a[i];
dfs(a,0,n);
cout << cst << endl;
}
system("pause");
}
update:11-2
支持不输出重复的组合,如【1,1,1】只输出一次,上面那个会输出多次[方法错误]
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
void perm(vector<int> ct,int n, int k, vector<vector<int> > &cnt){
if(k >= ct.size()){
cnt.push_back(ct);
return ;
}
for(int i = k;i < ct.size();i++){
if(ct[i] == ct[k] && i != k)
continue;
swap(ct[i],ct[k]);
perm(ct,n,k+1,cnt);
swap(ct[i],ct[k]);
}
}
int main(){
int n,tmp;
vector<int> ct;
vector<vector<int> > cnt;
while(cin >> n){
ct.clear();
cnt.clear();
while(n--){
cin >> tmp;
ct.push_back(tmp);
}
perm(ct, n, 0, cnt);
for(int i = 0;i < ct.size();i++)
cout << ct[i] << " *" ;
cout << endl;
for(int i = 0;i < cnt.size();i++){
for(int j = 0;j < cnt[i].size();j++){
cout << cnt[i][j] << " " ;
}
cout << endl;
}
}
}
下面才是正确的代码:
参加链接:http://www.zhizhihu.com/html/y2011/3674.html
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
/* 求排列 */
int cnt;
bool isok(int s[],int k,int i){
for(int j = k;j < i;j++)
if(s[j] == s[i])
return 1;
return 0;
}
void dfs(int s[], int k, int n){
if(k == n){
for(int i = 0;i < n;i++)
printf("%d ",s[i]);
printf("\n");
cnt++;
return;
}
for(int i = k;i < n;i++){
if(isok(s,k,i))
continue;
swap(s[i],s[k]);
dfs(s,k+1,n);
swap(s[i],s[k]);
}
}
int main(){
int s[100], n;
while(scanf("%d",&n) != EOF){
for(int i = 0;i < n;i++){
scanf("%d",&s[i]);
}
cnt = 0;
dfs(s,0,n);
printf("cnt = %d\n",cnt);
}
}
组合的过程:
#include <iostream>
using namespace std;
#include <cstdio>
#include <cstdlib>
#include <vector>
int size;
void dfs(vector<int> s,vector<int>& st,int pos,int n){
if(pos >= n){
for(int i = 0;i < st.size();i++)
printf("%d ",st[i]);
printf("\n");
size++;
return;
}
dfs(s,st,pos+1,n);
st.push_back(s[pos]);
dfs(s,st,pos+1,n);
st.pop_back();
}
int main(){
int n,key;
vector<int> s;
vector<int> st;
while(scanf("%d",&n) != EOF){
for(int i = 0;i < n;i++){
scanf("%d",&key);
s.push_back(key);
}
st.clear();
size = 0;
dfs(s,st,0,n);
printf("size = %d\n",size);
}
system("pause");
}