1208_可重复排列

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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值