将每个 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;
}