题解:AT_agc030_c [AGC030C] Coloring Torus

题意

给定 \(K\le 1000\),要求构造一个 \(n\times n\) 矩阵,满足:

  1. \(n\in[1,500]\)
  2. 每种颜色都出现了
  3. 每种颜色的格子周围的颜色(种类、个数)相同

思路

首先一个如下的拉丁方阵一定满足第 \(2,3\) 条限制:

\[\begin{matrix} 1,&2,&3,&\cdots,&n\\ n,&1,&2,&\cdots,&n-1\\ n-1,&n,&1,&\cdots,&n-2\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ 2,&3,&4,&\cdots,&1\\ \end{matrix} \]

但是这样构造只能构造出 \(K\le500\) 的情况。考虑调整。

注意到拉丁方阵中每个数的周围都是 \(x+1,x-1\) 各两个,很浪费,于是考虑把它改掉。

考虑一个 \(4\) 阶拉丁方阵,将任意一个对角线上的元素每隔一个 \(+4\),得到:

\[\begin{matrix} 1,&2,&3,&4\\ 4,&5,&2,&3\\ 3,&4,&1,&2\\ 2,&3,&4,&5\\ \end{matrix} \]

发现每个 \(2,4\) 周围都有一个 \(1\) 被改成了 \(5\),仍然满足第 \(2,3\) 条限制。容易证明的是,这种改法对于任意的 \(2k\) 阶方阵都成立,并且可以修改任意条对角线。于是从 \(n=500\) 开始构造,即可构造出所有 \(K\in[500,1000]\) 的解。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N=5e2+2;
int n,m,a[N][N];
signed main(){
    clock_t _st=clock();
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n;
    if(n<=500){
        m=n;
        for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)a[j][(i+j-1-1)%m+1]=i;
    }else{
        m=500;
        for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)a[j][(i+j-1-1)%m+1]=i;
        for(int i=1;i<=n-m;i++)for(int j=1;j<=m;j+=2)a[j][(i+j-1-1)%m+1]=i+m;
    }
    cout<<m<<'\n';
    for(int i=1;i<=m;i++){for(int j=1;j<=m;j++)cout<<a[i][j]<<' ';cout<<'\n';}cout<<'\n';
    clock_t _ed=clock();
    cerr<<(_ed-_st)*1.0/CLOCKS_PER_SEC<<'\n';
    return 0;
}
posted @ 2026-04-15 07:51  Redolent  阅读(2)  评论(0)    收藏  举报