版权声明:欢迎转载,若转载,请标明出处,如有错误,请指点,也欢迎大佬们给出优化方法 https://blog.csdn.net/Charles_Zaqdt/article/details/86533073
题目链接:http://nyoj.top/problem/139
康拓展开的裸题,对于康拓展开的定义是求当前的排列位于全排列中的第几个,比如132就是123的全排列的第二个,对于康拓展开的求法就是ans = ai*(n-1)!+ai*(n-2)!+....+ai*1!+ai*0!,对于ai的定义是当前这个数的后面还有多少个比它小的数。
AC代码:
#include <bits/stdc++.h>
using namespace std;
string str;
int n;
int Fun(int x){
return x == 0 ? 1 : x * Fun(x - 1);
}
int Contor(){
int sum = 0;
int len = str.length();
for(int i=0;i<len;i++){
int cnt = 0;
for(int j=i+1;j<len;j++){
if(str[i] > str[j]) cnt ++;
}
sum += cnt * Fun(len - i - 1);
}
return sum + 1;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>str;
printf("%d\n", Contor());
}
return 0;
}
那么对于康拓展开的逆运算,就是倒着去推就好了。
int resContor(int n,int k,int pre[]){
k--; // 排第k个,需要先减1
for(int i=0;i<n;i++){
int t = k / Fun(n - i - 1); // Fun求阶乘
for(int j=1;j<=n;j++){
if(vis[j] == false){
if(t == 0) break;
t --;
}
}
pre[i] = j;
vis[j] = true;
k %= Fun(n - i - 1);
}
}