zzqzzqzzq 喜欢构造题,于是又出了一道构造题。
你需要构造一个 n×nn\times nn×n的矩阵,每个格子里你需要填一个 1∼n21∼n^21∼n2 的整数。你需要保证第 iii 行恰好有 aia_iai 个不同的数,第 iii 列恰好有 bib_ibi 个不同的数,其中 ai,bi∈[2,n]a_i,b_i\in[2,n]ai,bi∈[2,n]
如果有解,给出任意一个解。如果无解,输出 −1−1−1。
盲猜有解
真实的构造题,做法就是先给主对角线填上 111 ,再给任意一条副对角线填上不同的 iii。
这样可以保证行列都至少有两个了,接下来一个一个位置填,如果行列都有剩余,那么填一个新的数,否则如果行有剩余,那么就填列的特有数,反之同理,如果行列都没有剩余,就填 111 ,那么就做完了。
#include<bits/stdc++.h>
using namespace std;
const int N=310;
int n,a[N],b[N],d[N][N],h[N],l[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]-=2;
for(int i=1;i<=n;i++) scanf("%d",&b[i]),b[i]-=2;
for(int i=1;i<=n;i++) d[i][i]=1;
for(int i=1;i<n;i++) h[i]=i+1,l[i+1]=i+1,d[i][i+1]=i+1;
h[n]=n+1;l[1]=n+1;d[n][1]=n+1;
int tot=n+1;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) if(!d[i][j]){
if(a[i] && b[j]){
a[i]--;b[j]--;
d[i][j]=++tot;
}
else if(b[j]) d[i][j]=h[i],b[j]--;
else if(a[i]) d[i][j]=l[j],a[i]--;
else d[i][j]=1;
printf("%d ",d[i][j]);
}
else printf("%d ",d[i][j]);
printf("\n");
}
}
本文介绍了一道构造题目,要求构建一个n×n矩阵,每行和每列都有特定数量的不同整数。通过递推填充策略,解决如何在给定条件下找到一个可能的解决方案。
189

被折叠的 条评论
为什么被折叠?



