[cf1261E]Not Same

问题可以这么理解——

构造一个$n+1$行$n$列的01矩阵$A$,满足:

1.第$i$列$n+1$个数的和为$a_{i}$

2.任意两行不完全相同

(对应关系:第$i$行第$j$列为1当且仅当第$i$次操作的集合包含$j$)

不妨将$a_{i}$从大到小排序,即$a_{1}\ge a_{2}\ge ...\ge a_{n}$,此时构造方案:

初始矩阵为0,$\forall 1\le i\le n$将第$i$列从第$i$行开始(包括第$i$行),下面$a_{i}$行填1(若行号大于$n+1$,则从第1行开始)

关于这一策略的正确性,即证明如此构造的矩阵$A$满足之前的两个条件:

对于第1个条件,由于$1\le a_{i}\le n$,显然成立

对于第2个条件,任取$i$和$j$(其中$1\le i<j\le n+1$),来证明第$i$行和第$j$行不完全相同——

取$(i,j]$中最小的$k$,满足$a_{k}+k>n+1$,对$k$分类讨论——

(1)不存在这样的$k$,必然有$a_{j}+j\le n+1$,此时$A_{i,j}=0$而$A_{j,j}=1$

(2)$k=i+1$,此时$A_{i,i+1}=0$而$A_{j,i+1}=1$

(3)不为以上两种情况,那么$a_{k-1}+(k-1)\le n+1$(否则显然取$k-1$)

注意到$a_{k-1}\ge a_{k}$,即$a_{k-1}+(k-1)+1\ge a_{k}+k$,前者$\le n+2$,后者$>n+1$,即两者都为$n+2$,也即$a_{k-1}+(k-1)=n+1$,此时$A_{i,k-1}=0$而$A_{j,k-1}=1$

综上,即得证

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 pair<int,int>a[N];
 5 int n,ans[N][N];
 6 int main(){
 7     scanf("%d",&n);
 8     for(int i=1;i<=n;i++){
 9         scanf("%d",&a[i].first);
10         a[i].first*=-1;
11         a[i].second=i;
12     }
13     sort(a+1,a+n+1);
14     for(int i=1;i<=n;i++){
15         int x=a[i].second;
16         for(int j=i;j<i-a[i].first;j++)
17             if (j<=n+1)ans[j][x]=1;
18             else ans[j-(n+1)][x]=1;
19     }
20     printf("%d\n",n+1);
21     for(int i=1;i<=n+1;i++){
22         for(int j=1;j<=n;j++)printf("%d",ans[i][j]);
23         printf("\n");
24     }
25 }
View Code

 

posted @ 2021-06-10 09:36  PYWBKTDA  阅读(68)  评论(0编辑  收藏  举报