苏州国决前集训Day11 模拟测试T2

z z q zzq zzq 喜欢构造题,于是又出了一道构造题。

你需要构造一个 n × n n\times n n×n的矩阵,每个格子里你需要填一个 1 ∼ n 2 1∼n^2 1n2 的整数。你需要保证第 i i i 行恰好有 a i a_i ai 个不同的数,第 i i i 列恰好有 b i b_i bi 个不同的数,其中 a i , b i ∈ [ 2 , n ] a_i,b_i\in[2,n] ai,bi[2,n]

如果有解,给出任意一个解。如果无解,输出 − 1 −1 1

盲猜有解

真实的构造题,做法就是先给主对角线填上 1 1 1 ,再给任意一条副对角线填上不同的 i i i

这样可以保证行列都至少有两个了,接下来一个一个位置填,如果行列都有剩余,那么填一个新的数,否则如果行有剩余,那么就填列的特有数,反之同理,如果行列都没有剩余,就填 1 1 1 ,那么就做完了。

#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");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值