康托展开和逆康托展开

康托展开和逆康托展开(康托展开)

#include <cstdio>

#include <string>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int fab[100];
int main(){
    string s;
    int k=0;

    cin>>s;
    int len=s.size();
    fab[0]=1;
    for(int i=1;i<100;i++) fab[i]=i*fab[i-1];
    for(int i=0;i<len;i++){
        int sum=0;
        for(int j=i+1;j<s.size();j++){
            if(s[j]<s[i]) sum++;
        }
        k+=fab[len-i-1]*sum;
    }
    printf("%d\n",k);
    //康托展开,已知一个字符串 求是第几个

    return 0;
}


#include <cstdio>
#include <string>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
int fab[100];
bool cmp(char x,char y){
    return x<y;
}
vector<char>v;
vector<char>re;
int main(){

    fab[0]=1;
    for(int i=1;i<100;i++) fab[i]=i*fab[i-1];

    int n,k;//n为这个字符串的位置,k为字符串的长度
    char s[100];
    scanf("%s",s);
    k=strlen(s);
    for(int i=0;i<k;i++) v.push_back(s[i]);
    scanf("%d",&n);
    for(int i=k;i>0;i--){
        int kk=n/fab[i-1];
        n%=fab[i-1];
        sort(v.begin(),v.end(),cmp);
        //printf("~~~%c\n",v[kk]);
        re.push_back(v[kk]);
        v.erase(v.begin()+kk);
    }
    for(int i=0;i<re.size();i++) printf("%c",re[i]);
    return 0;
}

//逆康托展开 已知是第几个 求字符串


//上述都是从0开始

(要注意题目是第几个,可能是从0开始或者从1开始)
(从1开始的话康托展开最后结果+1,
逆康托展开最后结果-1)