Codeforces 1236C. Labs
注意到 $f(X,Y)+f(Y,X)$ 是一个定值(因为每个元素都不相同)
所以如果能让 $f(X,Y)$ 与 $f(Y,X)$ 尽可能接近,那么一定是最优的
所以可以这样构造:把 $n^2$ 的序列每 $n$ 个分成一组,一共 $n$ 组
对于第一个集合,拿出当前第 $1$ 组最大的,第 $2$ 组最小的,第 $3$ 组最大的...以此类推
对于第二个集合,拿出当前第 $1$ 组最小的,第 $2$ 组最大的,第 $3$ 组最小的...以此类推
对于第三个集合,拿出当前第 $1$ 组最大的,第 $2$ 组最小的,第 $3$ 组最大的...以此类推
以此类推
然后可以发现,对于任意两个集合 $X,Y$ ,如果集合大小为偶数,$f(X,Y)$ 和 $f(Y,X)$ 的差值为 $0$ 否则为 $1$
因为显然集合大小为奇数时 $f(X,Y)$ 和 $f(Y,X)$ 不可能相等,那么此方案一定为最优方案
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=507; int n,A[N][N],L[N],R[N]; int main() { n=read(); int tot=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) A[i][j]=++tot; L[i]=1,R[i]=n; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if((i^j)&1) printf("%d ",A[j][L[j]++]); else printf("%d ",A[j][R[j]--]); } puts(""); } return 0; }