题解:AT_agc030_c [AGC030C] Coloring Torus
题意
给定 \(K\le 1000\),要求构造一个 \(n\times n\) 矩阵,满足:
- \(n\in[1,500]\)
- 每种颜色都出现了
- 每种颜色的格子周围的颜色(种类、个数)相同
思路
首先一个如下的拉丁方阵一定满足第 \(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;
}

浙公网安备 33010602011771号