ARC127B 题解

题解 · 2023-04-06

题意

给出 $n$ 和 $l$,要你构造 $3n$ 个长度为 $l$ 字符串,使得字符串都是由 0,1,2 组成且字符串两两不同,每个字符在每个字符串的同一位的出现次数都是 $n$ 次。
要你最小化你构造出来的字典序最大的字符串的字典序,输出 $3n$ 个字符串。

题解

我们可以将 $3n$ 个字符串分为0开头的,1开头的,2开头的。对于前两种字符串,它们的字典序显然不是最大的,因此既然要求最大字典序最小,我们就要考虑构造2开头的字符串,使得其最大字典序最小。

我们可以这样按照3进制下的 $[0,n)$ 贪心构造出 $n$ 个字符串,即可满足最小:

200...00000
200...00001
200...00002
200...00010
200...00011
200...00012
200...00020
...

而对于1开头和0开头的字符串,我们直接从2开头的置换而来即可。

#include<iostream>
using namespace std;
const int maxn=50010,maxl=20;
int n,l,a[maxn][maxl],b[maxn][maxl],c[maxn][maxl];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>l;a[1][1]=2;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=l;j++)a[i][j]=a[i-1][j];
        int k=l;
        a[i][l]++;
        while(k>1){
            if(a[i][k]>2)a[i][k]=0,a[i][--k]++;
            else break;
        }
    }//3进制贪心求n个2开头的字符串
    for(int i=1;i<=n;i++){
        for(int j=1;j<=l;j++)b[i][j]=(a[i][j]+1)%3;
        for(int j=1;j<=l;j++)c[i][j]=(a[i][j]+2)%3;//根据2开头的置换
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=l;j++)cout<<a[i][j];
        cout<<'\n';
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=l;j++)cout<<b[i][j];
        cout<<'\n';
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=l;j++)cout<<c[i][j];
        cout<<'\n';
    }
    return 0;
}
题解
Theme Jasmine by Kent Liao