# 解题报告：Codeforces Round #432 (Div. 1) D. Tournament Construction (DP+构造)

（点数<=30，0<=出度<=30）

#include<bits/stdc++.h>

using namespace std;

int n,m;
int A[35],ans[65],pos[65];
bool G[65][65],dp[65][35][2000];

void dfs(int a,int b,int c){
if(!a)return ;
ans[a--] = A[b];c-=A[b];
if(dp[a][b][c])return dfs(a,b,c);
return dfs(a,b-1,c);
}

inline void makeG(){
for(int i=1;i<=n;++i)pos[i]=i;
for(int i=1;i<=n;++i){
sort(pos+i,pos+n+1,[](int a,int b){return ans[a]<ans[b];});
for(int j=i+1;j<=i+ans[pos[i]];++j)G[pos[i]][pos[j]]=1;
for(int j=i+ans[pos[i]]+1;j<=n;++j)G[pos[j]][pos[i]]=1,ans[pos[j]]--;
}
}

int main()
{
scanf("%d",&m);n = 1 ;
for(int i=1;i<=m;++i)scanf("%d",&A[i]);
sort(A+1,A+m+1);dp[1][1][A[1]] = true;
while(n<62&&(n<m||!dp[n][m][n*(n-1)/2])){
for(int i=1;i<=m;++i)
for(int j=n*(n-1)/2,ed=n*A[m];j<=ed;++j)
if(dp[n][i][j])dp[n+1][i][j+A[i]] = dp[n+1][i+1][j+A[i+1]] = true;
++n;
}
if(n>61){
printf("=(\n");
return 0;
}
dfs(n,m,n*(n-1)/2);
printf("%d\n",n);makeG();
for(int i=1;i<=n;++i,printf("\n"))for(int j=1;j<=n;++j)
printf("%d",G[i][j]);
return 0;
}