题目链接:D-瑞瑞爱上字符串
题目描述:
瑞瑞最近迷上了字符串,因此决定出一个字符串的题。
给定两个正整数 N、K,考虑所有由 N - 2 个 a 和 2 个 b 组成的字符串,要求输出其中字典序第 K 小的。
例如当 N = 5 时,共有如下 10 种组成方式:
1、aaabb
2、aabab
3、aabba
4、abaab
5、ababa
6、abbaa
7、baaab
8、baaba
9、babaa
10、bbaaa
Input:
多组数据,第一行给定 T,表示数据组数。(1 ≤ T ≤ 1e4)
对于每组数据,给出两个正整数 N、K。(3 ≤ N ≤ 1e5, 1 ≤ K ≤ min(2e9, N * (N-1) / 2 ))
N 的总和不会超过 1e5。
Output:
对于每组数据,输出长度为 N 的字典序第 K 小的字符串。
Sample Input:
7
5 1
5 2
5 8
5 10
3 1
3 2
20 100
Sample Output:
aaabb
aabab
baaba
bbaaa
abb
bab
aaaaabaaaaabaaaaaaaa
思路:
既然只有ab两种字符,且只有两个b,那么只需要考虑b的位置就OK了。对于n个字符,优先级顺序共有(n-1)(1+n-1)/2种。首先确定第一个b的位置,不妨令第一个b在i坐标处且在第二个左边,则第二个b的位置有n-i个,不妨使第二个b在尾端,找到不大于k的最大值,然后左移第二个b即可。
代码:
#include<iostream>
using namespace std;
const int maxn=2e5+10;
int T;
long long n,k,a,b,op;
int main(){
cin>>T;
while(T--){
cin>>n>>k;
for(long long i=1;i<=n;i++)
if(i*(i+1)/2>=k){
op=i;
break;
}
for(int j=1;j<=n;j++){
if(j==n-op||j==n-(k-(op-1)*op/2-1))
cout<<'b';
else
cout<<'a';
}
cout<<endl;
}
return 0;
}