Description
设 R = { r1, r2, …, rn } 是一个 n-元多重集. 试列出 R 的所有不同排列.
Input
有多个测试用例. 每个测试用例由一个自然数 n(n ≤ 500) 以及一个小字字母字符串组成, 表示问题中的 n-元多重集. 输入直至没有数据或者 n=0 为止.
Output
对于每个测试用例按字典顺序输出给定多元集的所有可重复 n-排列, 每个排列占一行. 在所有排列输出之后, 输出一行包含表示排列个数的一个整数.
Sample Input
4
aacc
Sample Output
aacc
acac
acca
caac
caca
ccaa
6
Hint
由于需要大量的数据输出, 因此使用 C++的流 IO 可能会超时. 建议使用 printf 或 puts 输出字符串.
解法1
用回溯超时了。。。
#include<vector>
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string>
using namespace std;
void backtrack(string& output, string& nums,vector<int>& vis,int & count){
// 所有数都填完了
if (output.size() == nums.size()) {
cout << output << endl;
++count;
return;
}
for (int i = 0; i < nums.size(); ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
output.push_back(nums[i]);
vis[i] = 1;
backtrack(output, nums,vis,count);
output.erase(output.end()-1);
vis[i] = 0;
}
}
void permute(string& nums,int &count) {
string output;
vector<int> vis(nums.size(), 0);
sort(nums.begin(), nums.end());
backtrack(output, nums,vis,count);
}
int main() {
int n;
string nums;
while(cin>>n) {
cin >> nums;
int count = 0;
permute(nums,count);
cout << count << endl;
}
system("pause");
return 0;
}
解法2
还是超时。。。
#include<stdio.h>
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string a;
int nextStr(int n)
{
int j;
string right;
for (int i = n - 2; i >= 0;--i){
if(a[i]<a[i+1]){
j = i + 1;
while(j<n&&a[j]>a[i]){
++j;
}
--j;
right = a.substr(i + 1, j - i - 1) + a[i] + a.substr(j + 1);
reverse(right.begin(),right.end());
a = a.substr(0, i) + a[j] + right;
cout << a << endl;
return 1;
}
}
return 0;
}
int main()
{
int n;
char k;
while(cin>>n) {
if(n==0){
break;
}
int count = 1;
cin >> a;
while(nextStr(n)){
++count;
}
cout << count << endl;
}
return 0;
}
解法3
最后发现stl中下一个排列的函数,就没有超时了,裂开。。。
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
string s;
int main() {
int n;
while(cin >> n){
cin >> s;
std::sort(s.begin(), s.end());
int count=0;
do {
cout<<s<<endl;
++count;
} while (next_permutation(s.begin(), s.end()));
std::cout << count<< std::endl;
}
return 0;
}