題目鏈接
題目
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; }