• AISing Programming Contest 2021(AtCoder Beginner Contest 202)D题题解


    D - aab aba baa

    题面

    Among the strings of length (A + B) containing (A) occurrences of a and (B) occurrences of b, find the string that comes (K)-th in the lexicographical order.

    题面意思是给定(A)a(B)b所组成的字符串,问若按字典序排列这个字符串,则按照从小到大第(K)个字典序的字符串表示是什么。

    样例解释:

    2 2 4
    

    两个a和两个b组成的字符串的字典序从小到大为: aabb, abab, abba, baab, baba, bbaa
    第四个为baab,即答案为baab

    解题思路

    只有'a','b'两个字母,且跟排列有关,于是想试试他的K值是否与组合数有关。

    最后找到了如下关系:

    (根据高中数学 (C_{a+b}^{a})的值即为所有组合情况)

    cur表示能构造出前cur个字典序,初始化为0(现在不能理解没有关系)
    设输入的a为剩余a的数量
    设输入的b为剩余b的数量
    设输入的k为第k个字典序字符串

    现在假设按样例输入

    2 2 4
    

    一共四位值,则假设第一位值是a,
    那么现在所有的组合数为 (C_{a+b-1}^{a-1})

    (d=C_{a+b-1}^{a-1})

    则 d + cur 为能覆盖到的字典序(d+cur及之前的字典序都能实现)

    (d + cur >= k) 则说明第一位为a的情况下,a这个位置满足条件,后面可以继续构造)
    否则说明当前位不能为a,则输b然后cur += d。

    代码如下

    #include <iostream>
    
    using namespace std;
    
    typedef long long ll;
    const int N = 100;
    
    ll q[N][N];
    
    
    /* 求组合数 */
    void solve ( void )
    {
        for ( int i = 0; i < N; i++ )
        {
            for ( int j = 0; j <= i; j++ )
            {
                if ( !j )
                {
                    q[i][j] = 1;
                    continue;
                }
    
                q[i][j] = q[i - 1][j] + q[i - 1][j - 1];
            }
        }
    }
    
    ll C ( ll a, ll b )
    {
        return q[a][b];
    }
    
    int main ( void )
    {
        solve();	/* 预处理组合数 */
    
        ll a, b, k;
        cin >> a >> b >> k;
    
        for ( ll m = a + b, i = 0, cur = 0; i < m; i++ )
        {
            ll d = C( a + b - 1, a - 1 );
    
            if ( a == 0 ) cout << 'b';
            else if ( b == 0 ) cout << 'a';
            else if ( k <= cur + d ) cout << 'a', a--;
            else cout << 'b', b--, cur = min ( k, cur + d );
        }
    
        return 0;
    }
    
    作者:Jude_Zhang
    关于博主:评论和私信会在第一时间回复。或者直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用BY-NC-SA 许可协议。转载请注明出处!
    支持博主:如果您觉得文章对您有帮助,可以点击文章下方赞一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    el-select下拉框选项太多导致卡顿,使用下拉框分页来解决
    vue+elementui前端添加数字千位分割
    Failed to check/redeclare auto-delete queue(s)
    周末啦,做几道面试题放松放松吧!
    idea快捷键
    解决flink运行过程中报错Could not allocate enough slots within timeout of 300000 ms to run the job. Please make sure that the cluster has enough resources.
    用.net平台实现websocket server
    MQTT实战3
    Oracle 查看当前用户下库里所有的表、存储过程、触发器、视图
    idea从svn拉取项目不识别svn
  • 原文地址:https://www.cnblogs.com/judezhang/p/14810546.html
Copyright © 2020-2023  润新知