Educational Codeforces Round 119 (Div. 2), (C) BA-String硬着头皮做, 能做出来的

题目链接  

Problem - C - Codeforces

 

题目

 

 

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;
}

 

posted @ 2021-12-19 19:32  la-la-wanf  阅读(181)  评论(4编辑  收藏  举报