Official

C - One More aab aba baa Editorial by en_translator


In this editorial, we will introduce the following two solutions.

  1. Solution by searching
  2. Solution using next_permutation

1. Solution by searching

Consider enumerating all possible strings that can be obtained as a permutation of each character.
Basically, the permutations of characters can be obtained in the similar way to enumerating the permutations of \((1,2,\dots,|S|)\).
This strategy can be easily implemented with a recursion. We can recursively choose one character of \(S\) that is not yet consumed, and append it to the preliminary string we are searching. In order to manage which character is already consumed, we can use the binary representation of an integer.
Once we have enumerated the strings, we can finally sort them and remove the duplicates to find the answer.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

int l;
string s,t;
vector<string> res;

void find(int fl){
  if(fl==0){
    res.push_back(t);
    return;
  }
  for(int i=0;i<l;i++){
    if(fl&(1<<i)){
      t.push_back(s[i]);
      find(fl^(1<<i));
      t.pop_back();
    }
  }
}

int main(){
  int k;
  cin >> s >> k;
  l=s.size();
  find((1<<l)-1);
  sort(res.begin(),res.end());
  unique(res.begin(),res.end());
  cout << res[k-1] << '\n';
  return 0;
}

2. Solution using next_permutation

There is an algorithm called next_permutation that finds the next permutation lexicographically succeeding to the current permutation.
We do not introduce the internals details of next_permutation, but this function works even when the elements have duplicates, and for C++, it is implemented as a standard library.
This enables us to enumerate the permutations with quite a very concise code.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  string s;
  int k;
  cin >> s >> k;
  sort(s.begin(),s.end());
  while(k>1){
    next_permutation(s.begin(),s.end());
    k--;
  }
  cout << s << '\n';
  return 0;
}

posted:
last update: