CF1236C Labs 题解
CF1236C Labs
这题一眼看上去没有任何思路,观察到 $n \le 300$,且每个数对应的答案一定,可以找找规律。
样例中 $n=3$ 时,不难发现构造方法:
若为奇数列则从上往下递增,若为偶数列则从下往上递增。
正确性并不难证明:
由题目可知 $f(G_i,G_j) + f(G_j,G_i) = n^2$,那么让 $f(G_i,G_j)$ 和 $f(G_j,G_i)$ 都尽量接近 $\dfrac{n^2}{2}$ 即可。
分情况讨论:若 $n$ 为偶数,按照上述构造方法,可得 $\min(f(G_i,G_j)) = \dfrac{n^2}{2}$
(因为两行之间的大于小于关系都是对称的,写几组就能明白。)
若 $n$ 为奇数,则拆成 $n-1$ 和 $1$ 两部分来看,前半部分贡献为 $f(G_i,G_j)=f(G_j,G_i)=\dfrac{(n-1)^2}{2}$。
而 $G_i$,$G_j$$(i \lt j)$ 中的最后一个数,对 $f(G_i,G_j)$ 的贡献为 $n-1$,对 $f(G_j,G_i)$ 的贡献为 $n$。
那么 $\min(f(G_i,G_j)) = \dfrac{(n-1)^2}{2} + n - 1 = \dfrac{n^2-1}{2}$。
综上,该构造方法恰能使得 $f(G_i,G_j)$ 的最小值最大 。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 305; 6 int n,a[maxn][maxn]; 7 int main() { 8 scanf("%d",&n); 9 int cnt = 0; 10 for(int i = 1;i <= n;++ i) { 11 if(i & 1) { 12 for(int j = 1;j <= n;++ j) { 13 a[j][i] = ++ cnt; 14 } 15 } 16 else { 17 for(int j = n;j;-- j) 18 a[j][i] = ++ cnt; 19 } 20 } 21 for(int i = 1;i <= n;++ i) { 22 for(int j = 1;j <= n;++ j) { 23 printf("%d ",a[i][j]); 24 } 25 putchar('\n'); 26 } 27 return 0; 28 }