题解 P6497 [COCI2016-2017#2] Prosječni
洛谷。
题意
显然。
分析
肯定先分析一行的情况,我们在每一行都只有一个限制,就是 $n$ 个数的平均数是这一行中的数之一。
因为我们的方案其实与我们数字的顺序无关,因此,我们使这一行从小到大排序,开头为 $st$。
考虑什么情况下满足。
当然是从简单的开始想,分为 $n$ 为奇数与偶数的情况。
在是奇数时,我们从简单开想,($k$ 是公差)。
| $st$ | $st+k$ | $st+k+k$ | $\dots$ | $st+k\times (n-1)$ |
|---|
这样显然是满足的,平均数为 $\frac{st+k\times (n-1)}{2}$,是在此行内的。
在是偶数时:
| $st$ | $st+k$ | $\dots$ | $st+k\times (n-2)$ | $en$ |
|---|
为什么是最后一个另设了 $en$ 呢,因为此时我们的平均数并不是一个整数。
所以我们要使 $en$ 满足我们的条件。
最好要使 $en$ 尽量小,我们的 $en$ 应当也是带 $k$ 的,这样才能使其平均数在其之内,好算的,我们的 $en=st+\frac{(n+2)\times k}{2}$,平均数为 $st+\frac{k*(n^2-2\times n+4)}{2}$,此数必然是一个整数,并且小于等于 $st+k\times (n-2)$ 是满足的。
最后就令行的 $k=1$,那么为了数字不同并且竖列也满足这个条件,我们令竖行的 $k$ 为第一行的最大值。
说的可能并不是那么明白,看代码更好理解。
cin>>n;
if(n&1) {
int cnt=0;
for(int i=1; i<=n; ++i) {
for(int j=1; j<=n; ++j) printf("%d ",++cnt);
puts("");
}
} else if(n==2) {
puts("-1");
} else {
int x=n/2+n;
for(int i=1; i<n; ++i) {
for(int j=1; j<n; ++j) printf("%d ",j+(i-1)*x);
printf("%d\n",i*x);
}
for(int j=1; j<n; ++j) printf("%d ",j+(n-1)*x+((x-n)*x));
printf("%d",n*x+(x*(x-n)));
}

浙公网安备 33010602011771号