枚举排列,就是生成关于一个数列的所有排列
这个数列又分为有重(有至少两个变量值一样)和无重(相当于集合)的
可以用递归来做
下面是算法书给出的伪代码:
void print_permutation(序列A, 集合S)
{
if(S为空) 输出序列A;
else//按从小到大的顺序考虑S的每个元素v
{
print_permutation(在A的末尾添加v后得到的新序列, S - {v})
}
}
下面是我写的:
#include<cstdio>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
set<int> s;
map<int, int> m;
int ans[1000000], cnt;
void print_permutation(int cur){
if(cur == cnt){
for(int i = 0; i < cur; i++) printf("%d ", ans[i]);
putchar('\n');
}
else{
for(auto it = s.begin(); it != s.end(); it++)
if(m[*it]){
m[*it]--;
ans[cur] = *it;
print_permutation(cur + 1);
m[*it]++;
}
}
}
int main(void)
{
int tmp;
while(scanf("%d", &tmp) == 1 && tmp){
if(m.count(tmp)) m[tmp]++;
else{m[tmp] = 1; s.insert(tmp);}
cnt++;
}
print_permutation(0);
return 0;
}
当然这个代码用了太多的全局变量,想要少用点可以用指针
或者有另一种解决办法,就是用STL库中的next_permutation函数:
#include<cstdio>
#include<algorithm>
using namespace std;
int num[1000000], cnt;
int main(void)
{
int tmp;
while(scanf("%d", &tmp) == 1)
num[cnt++] = tmp;
sort(num, num + cnt);
do{
for(int i = 0; i < cnt; i++) printf("%d ", num[i]);
putchar('\n');
}while(next_permutation(num, num + cnt));
return 0;
}
会自动生成下一个序列,而当没有下一个序列的时候就结束
具体可以上网查查,这里就不赘述了
一些废话:
清明放假宅宿舍爽玩了4天,现在水个文发发