Atcoder Beginner Contest 202 题解

A.B比较简单,主要想说下C.D的做法

C-Made Up

题目链接
有三个数组 A A A=( A 1 A_1 A1, A 2 A_2 A2,…), B B B=( B 1 B_1 B1, B 2 B_2 B2,…), C C C=( C 1 C_1 C1, C 2 C_2 C2,…),问有多少对 A i A_i Ai= B C j B_{C_j} BCj?(有点逆过来做的思想)
我的做法是用cnt数组记录A数组中出现的每个数的个数,cnt[a[i]]++,最后对C数组遍历,因为C数组中的数是B数组中的索引,ans+=cnt[b[c[i]]].

#include
using namespace std;

typedef long long ll;
const int N=1e5+10;
int a[N],b[N],c[N],cnt[N];
ll ans;

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i],cnt[a[i]]++;
    for(int i=1;i<=n;i++)cin>>b[i];
    for(int i=1;i<=n;i++)cin>>c[i];
    for(int i=1;i<=n;i++)ans+=cnt[b[c[i]]];
    cout<<ans<<endl;
    return 0;
}

D-aab aba baa

题目链接
在长度为A+B的字符串有A次a出现,B次b出现,找出按字典序排列第K个的字符串。(组合数+思维)
第一个样例的解释如下:2个a出现,2个b出现,按字典序排序如下:aabb,abab,abba,baab,baba,bbaa.第4个即baab.
从第1位开始枚举每一位,显然要构成一个a个a和b个b组成的字符串,第1位是a的有 C a + b − 1 a − 1 C_{a+b-1}^{a-1} Ca+b1a1个数,判断当前的k和它的关系(用now存),

if(k > now) k -= now, putchar('b'), --b;
        else putchar('a'), --a;

第2位是a的话是有 C a + b − 2 a − 1 C_{a+b-2}^{a-1} Ca+b2a1…(n=a+b)即

 for(int i=1; i<=n; i++) {
        ll now = C[n-i][a - 1];//注意a=0时的情况

代码如下:

#include
using namespace std;

typedef long long ll;
const int N=110;
ll C[N][N];

void get_C(int n) {
    C[0][0] = 1;
    for(int i = 1; i <= n; i++) {
        C[i][0] = 1;
        for(int j = 1; j <= i; j++)
            C[i][j]= C[i - 1][j] + C[i - 1][j - 1];
    }
}

int main(){
    int a,b;
    ll k;//这里注意开long long 煞笔了
    cin>>a>>b>>k;
    get_C(60);
//    for(int i=0;i<=n;i++){
//        for(int j=0;j<=n;j++) {
//            cout<
//        }
//        cout<
//    }
//    cout<
    int n=a+b;
    for(int i=1; i<=n; i++) {
        ll now = C[n-i][a - 1];//注意a=0时的情况
        if(a==0)now=0;
//        cout<<"now:"<
        if(k > now) k -= now, putchar('b'), --b;
        else putchar('a'), --a;
    }
    return 0;
}

你可能感兴趣的:(Atcoder,算法,数据结构,字符串,leetcode,acm)