zoukankan      html  css  js  c++  java
  • 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 许可协议。转载请注明出处!
    支持博主:如果您觉得文章对您有帮助,可以点击文章下方赞一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    Linux_文件权限
    离殇
    Oracle数据库软件标准版的一个限制:仅仅能用一个rman channel
    数据结构和算法设计专题之---推断两个链表是否相交并找出交点
    Test for Job (poj 3249 记忆化搜索)
    表达式求值
    HDOJ 2196 Computer 树的直径
    ListView的position的保持
    Django訪问量和页面PV数统计
    【oracle 11G Grid 】Crsctl start cluster 和 crsctl start crs 有差别么?
  • 原文地址:https://www.cnblogs.com/judezhang/p/14810546.html
Copyright © 2011-2022 走看看