1. 程式人生 > 其它 >AT4512 [AGC030C] Coloring Torus 題解

AT4512 [AGC030C] Coloring Torus 題解

AT4512 [AGC030C] Coloring Torus

給出一個數字 \(K(≤1000)\)

要求構造出一個 \(n(≤500)\)\(n\) 列的矩陣

滿足:

  • \(∀i,j∈[1,n],A[i,j]∈[1,K]\)

  • \(∀v∈[1,K],∃i,j∈[1,n],A[i,j]=v\)

  • 定義\(cnt_{i,j,v}\)表示周圍 \(4\) 個格子數字等於 \(v\) 的個數,\(∀v∈[1,K]\)\(A[i][j]=A[i'][j']\) 則要求 \(cnt_{i,j,v}=cnt_{i',j',v}\)

sol

通過樣例,我們可以得出 \(n≤500\) 時的構造方法

1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5

然後考慮怎麼將 \(K\) 擴大到 \(1000\)

考慮一行的數等價性,然後再考慮題目給的迴圈是什麼意思,就是在給定的空間裡構造出儘可能多的行!

於是我們想到了對角線構造

1 2 3 4 5
6 1 2 3 4
7 6 1 2 3
8 7 6 1 2
9 8 7 6 1

現在就能構造出 \(2n-1\)\(K\)

但如果 \(K\)是偶數了,考慮對上面方法進行改造

發現一個斜線上的數是等價的,所以把一個斜線上交錯放上一些多餘的數是不影響答案的

就變成了這樣

1 2 3 4 5
6 10 2 3 4
7 6 1 2 3
8 7 6 10 2
9 8 7 6 1

就可以將偶數的情況構造出來了

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
int K;
int nx[maxn];
int mp[maxn][maxn];
int main(){
	freopen("AT4512.in","r",stdin);
	freopen("AT4512.out","w",stdout);
	scanf("%d",&K);
	if(K<=500){
		printf("%d\n",K);
		for(int i=1;i<=K;i++){
			for(int j=1;j<=K;j++)
				printf("%d ",i);
			printf("\n");
		}
	}else {
		int n=500,N=0;
		for(int i=1;i<=n;i++)nx[i]=i+1;
		nx[n]=1,printf("%d\n",n);K-=n;
		for(int i=1;i<=n;i++){
			int a=++N,b=K?++N:N;
			K-=b-a;
			for(int x=1,y=i;x<=n;x++,y=nx[y])
				mp[x][y]=x&1?a:b;
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)
				printf("%d ",mp[i][j]);
			printf("\n");
		}
	}
	return 0;
}