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;
}

 

posted @ 2019-10-18 16:57  LLTYYC  阅读(358)  评论(0编辑  收藏  举报