#include <bits/stdc++.h>
using namespace std;
int V,len,now,cnt[27],sum[27];
int get_max(int len)
{
return ((len-(len/26+1))*(len/26+1)*(len%26)+(26-len%26)*(len/26)*(len-len/26))/2;
}
bool check(int x,int n) //第i位放x后,后面剩余的n个位置有没有办法放字母使满足条件
{
memset(cnt,0,sizeof(cnt));
int add1 = 0,add2 = 0;
for(int j = 26;j >= x+1;j--)
add1 += sum[j];
sum[x] ++;
for(int L = 1;L <= n;L++)
{
int ma = -1,pos = 0,num = 0;
for(int j = 26;j >=1;j--)
{
if(L-1-cnt[j] +num > ma)
{
ma = L-1-cnt[j] +num;
pos = j;
}
num += sum[j];
}
add2 += ma,cnt[pos]++;
}
if(now + add1 +add2 >= V)
{
now += add1;
return true;
}
else
{
sum[x]--;
return false;
}
}
int main()
{
string ans = "";
cin >> V;
for(int i = 1;;i++)
{
if(get_max(i) >= V) //找到了能满足V个逆序对的字串最短长度
{
len = i;
break;
}
}
for(int i = 1;i <= len;i++) //按长度从左往右放字母
{
for(int j = 1;j <= 26;j++)
{
if(check(j,len-i))
{
ans += char(j+'a'-1);
break;
}
}
}
cout << ans << '\n';
return 0;
}
要求顺序:abcd。。。。
冒泡排序交换的次数 = 串中的逆序对数量
每插入一个字母,逆序对的数量增加数 = 插入字母前大于该字母的字母数量+ 插入字母后小于该字母的字母数量