神奇 ad-hoc 题。

考虑到 \(a_{i,j}\) 值域为 25 内,考虑根号分治,取块长 \(23 \leq p\leq 25\)。对于根号块内,我们找出一个矩阵,使得每一行,每一列的数都不同,记这个矩阵为 \(P_0\),考虑 \(P_i\) 为将行整体向上移动 \(i\) 次后的矩阵(如果超出边界就循环到矩阵最下面)

考虑整个图,我们用 \(P_i\) 铺满这个图,此时如果有问题,那么这四个角一定在四个不同的块。

考虑若 \(a,b,c,d\) 这四个块(依次为左上,右上,左下,右下)出问题了,那么我们找到 \(a,b\) 任意一行的任意一个颜色,将他们对下来在 \(c,d\) 块中找到对应的颜色,若这两个颜色在同一行那么就出问题了。

\(f(u)\) 表示 \(u\) 这个块的矩阵为 \(P_{f_u}\),按照上面的描述,一定有 \(f(c)-f(a) \equiv f(d)-f(b)\pmod p\)

考虑构造一个满足不存在这样的 \(p\times p\) 的矩阵,不难想到取根号块长度为 \(23\)(质数),然后第 \(i\) 行(从 \(0\) 标号)排上 \(P_{0},P_{i},P_{2i}...\),根据逆元的知识知道此时一定合法的情况。

#include<bits/stdc++.h>
using namespace std;
#define p 23
int a[50][50][50],b[50][50],ans[700][700];
int main(){
    for(int j=0;j<p;j++)
        for(int k=0;k<p;k++)
            for(int i=0;i<p;i++)
                a[j][(i+j)%p][(i+k)%p]=k;
    for(int i=0;i<p;i++){
        for(int j=0;j<p;j++){
            b[i][j]=i*j%p;
        }
    }
    for(int i=0;i<p;i++)for(int j=0;j<p;j++){
        for(int x=0;x<p;x++)for(int y=0;y<p;y++)
            ans[i*p+x][j*p+y]=a[b[i][j]][x][y];
    }
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            printf("%d ",ans[i][j]+1);
        }
        puts("");
    }
}