CF37C

将每个 01 串看作一个二进制数,将长度从小到大排序,对于当前第 \(i\) 个串,首先在第 \(i-1\) 个串的基础上加 \(1\)(如果不能加 \(1\) 即爆位数则无解),如果长度相同则无需任何操作,否则按照缺少的长度从后面补 \(0\)。这样做能保证长度短的不为长度长的前缀,且尽可能的多填数。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
struct L{
    int v,id;
    int c[1010];
    L(){c[0]=1;}
}a[1010],ans[1010];
int n,flag,pp[1010];
bool cmp(L x,L y){
    return x.v<y.v;
}
bool add(int i){
    for(int j=a[i].c[0];j>=1;j--){
        if(a[i].c[j]==0){
            a[i].c[j]=1;
            return true;
        }
        a[i].c[j]=0;
    }
    return false;
}
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].v,a[i].id=i;
    sort(a+1,a+n+1,cmp);
    a[1].c[0]=a[1].v;
    for(int i=1;i<=a[1].v;i++)
        a[1].c[i]=0;
    for(int i=2;i<=n;i++){
        for(int j=0;j<=a[i-1].c[0];j++)
            a[i].c[j]=a[i-1].c[j];
        if(!add(i)){
            cout<<"NO";
            return 0;
        }
        a[i].c[0]=a[i].v;
        // cout<<a[i].c[0]<<endl;
    }
    for(int i=1;i<=n;i++)
        ans[a[i].id]=a[i];
    cout<<"YES\n";
    for(int i=1;i<=n;i++){
        for(int j=1;j<=ans[i].c[0];j++)
            cout<<ans[i].c[j];
        cout<<'\n';
    }
    return 0;
}
posted @ 2025-09-12 19:39  FormulaOne  阅读(6)  评论(0)    收藏  举报