题目链接
题目
Example
input
3 2 4 3 a* 4 1 3 a**a 6 3 20 **a***
output
abb
abba
babbbbbbbbb
题意
n--字符串长度, k--每个星号最多代表k个b , x--第x小的字符串s的子串(可以是不连续子串)
每一个星号可以换成0~k个b, 需要求出第x小的字符串s的子串.
题解
a****a***a**(连续的星号指两个a或者边缘之间夹的星号, 可以为1)
从后面往前看(两个星号), 对于相邻的cnt个星号, 它们可以有cnt*k+1(下方以res代替)种出现方式, 即0~cnt*k个b。
再往前看(三个星号), 前面每多一种情况, 整体就多上面的res个, 也就是(cnt*k+1) * res。
但是, 每段连续的星号要放多少个b呢?
还是从后往前看, 每次遇到连续的星号, x/(cnt*k+1), 连续的星号的情况个数为x%(cnt*k+1)。
值得注意的是, 在一切的开始之时x--了!!! ----------> 因为排名是从1开始的, 不是0, 所以-1。
AC代码
#include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { int t; cin >> t; while(t --) { LL h[2010]={0}; int n, k; LL x; string s; cin >> n >> k >> x>> s; x --;//排名是从1开始的, 不是0, 所以-1. LL now=1; int cnt = 0; for(int i = n-1; i >= 0 && x != 0; i --) { if(s[i]=='*')cnt ++; else if(cnt>0) { h[i] = x % ((LL)cnt*k+1); x /= ((LL)cnt * k +1); cnt = 0; } } for(int i=0;i<x;i++)cout << "b";//最前面没有a,不能赋值给h[i] for(int i =0; i < n; i ++) { if(s[i] == 'a') { cout << 'a'; for(int j = 0; j < h[i] ; j ++)cout << 'b'; } } cout << endl; } return 0; }