求213在123,132,213,231,312,321中排第几。
我们定义数列a。
an
表示数第n位在第1位到第n位中是第几小(从0开始算)
比如:对213求它的a数列为
{1,0,0}
a3
表示2在
{1,2,3}
是第2小所以
a3=1
a2
表示1在
{1,3}
是第1小所以
a2=0
a1
表示3在
{3}
是第1小所以
a1=0
康托展开为:
ans=an×(n−1)!+an−1×(n−2)!+...+a2×1!+a1×0!
对于排列4213来说,4在4213中排第3,注意从0开始,2在213中排第1,1在13中排第0,3在3中排第0,即: a={3,1,0,1} ,这样得到4213在所有排列中排第ans=20。
//康托展开
LL Work(char str[])
{
int len = strlen(str);
LL ans = 0;
for(int i=0; i<len; i++)
{
int tmp = 0;
for(int j=i+1; j<len; j++)
if(str[j] < str[i]) tmp++;
ans += tmp * f[len-i-1]; //f[]为阶乘
}
return ans; //返回该字符串是全排列中第几大,从1开始
}
康托展开的逆运算从 (n−1)! 开始到 0! %一下就好了
//康托展开逆运算
void Work(LL n,LL m)
{
n--;
vector<int> v;
vector<int> a;
for(int i=1;i<=m;i++)
v.push_back(i);
for(int i=m;i>=1;i--)
{
LL r = n % f[i-1];
LL t = n / f[i-1];
n = r;
sort(v.begin(),v.end());
a.push_back(v[t]);
v.erase(v.begin()+t);
}
vector<int>::iterator it;
for(it = a.begin();it != a.end();it++)
cout<<*it;
cout<<endl;
}