AISing Programming Contest 2021(AtCoder Beginner Contest 202)(补题)

D - aab aba baa

在这里插入图片描述在这里插入图片描述
题意: 就是给你A个‘a’和B个‘b’,由a和b组成的所有字符串按字典序排列,输出第k个字符串。
思路:和全排列有关,对于所有的排列情况,就是C(a+b,a).假设n=A+B.
假设第一个字母你确定为‘a’那么你看剩下A-1个‘a’和B个‘b’的组合情况。
如果小于K,说明你选‘a’是不合法的。不合法的原因是,C(n-1,a-1)这个数比k还小,说明现在以a开头的字符串在字典序的顺序中已经在第k个之前了,只能选‘b’了。来使字符串在字典序中的顺序靠后。
如果大于等于K, 说明选‘a’是合法的.合法的原因是,C(n-1,a-1)这个数比k还大,说明现在以a开头的字符串在字典序的顺序中已经在第k个之后了(或者等于),可以靠后面的字符串的组合来使字符串在字典序中的位置处在第K位置。
所以,需要预处理出来组合数来,组合数的处理需要用 C ( i , j ) = C ( i − 1 , j ) + C ( i − 1 , j − 1 ) C(i,j)=C(i-1,j)+C(i-1,j-1) C(i,j)=C(i1,j)+C(i1,j1)
当j等于0时, C ( i , 0 ) = 1 C(i,0)=1 C(i,0)=1
来求出所有的组合数情况,然后在利用上面的假设,从前往后对每个位置都进行判断选‘a’还是选‘b’,选‘b’的时候,K要减去当前位置选‘a’的所有情况数(这些都是无效情况了,要减去),当只剩下a或者b的时候就直接输出对应的字母。
下面附上代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e6+10;
#define ll long long
ll dp[63][63];
int a,b;
ll k;
void pre() {
    for(int i=0;i<=61;i++) {
        dp[i][0]=1;
    }
    for(int i=1;i<=60;i++) {
        for(int j=1;j<=i;j++) {
            dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
        }
    }
}
int main() {
    pre();
    cin>>a>>b>>k;
    int n=a+b;
    for(int i=1;i<=n;i++) {
        if(a==0) {
            while(b) {
                cout<<'b';
                b--;
            }
            return 0;
        }
        if(b==0) {
            while(a) {
                cout<<'a';
                a--;
            }
            return 0;
        }
        if(k<=dp[n-i][a-1]) {
            a--;
            cout<<"a";
        }
        else {
            b--;
            cout<<"b";
            k-=dp[n-i][a-1];
        }
    }
    return 0;
}

E题涉及启发式合并,暂时没学,学完这个算法后再来补
F涉及凸包算法
现在会的算法还太少,最后两个题设计的算法,还不太会,先学再补。
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值