AT4512 [AGC030C] Coloring Torus 題解
阿新 • • 發佈:2021-11-11
link
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; }