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;
}
我们会走到一起的。

浙公网安备 33010602011771号