把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

题解 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)));
}
posted @ 2023-08-24 20:25  djh0314  阅读(59)  评论(0)    收藏  举报  来源
浏览器标题切换
浏览器标题切换end