https://codeforces.com/problemset/problem/1118/C
思路:
画出来可得,n是偶数,每个数需要是%4==0.
n为奇数除了十字线上,其他地方也要是4的倍数。
讲下模拟的细节。
偶数的话直接check每个数%4.
奇数的话需要>=4减了之后,然后构造十字线,十字线上是否每个>=2(先跳过中心点)。然后最后check一下。
输出的话,观察到其他的小矩形是左上角矩形的旋转。每一个模拟出来扔到ans[][]里去最后统一check完了之后再判输出。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=30;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL a[maxn*maxn];
map<LL,LL>map1;
LL ans[maxn][maxn];
void pri(LL n){
for(LL i=1;i<=n;i++){
for(LL j=1;j<=n;j++){
cout<<ans[i][j]<<" ";
}cout<<"\n";
}
}
bool check1(){
for(auto i:map1){
if(i.second%4!=0) return false;
}
return true;
}
bool check2(LL n){
for(LL i=1;i<=n;i++){
if(i==n/2+1) break;
for(auto &j:map1){
if(j.second>=2){
j.second-=2;
ans[i][n/2+1]=j.first;
ans[n-i+1][n/2+1]=j.first;
break;
}
}
}
for(LL j=1;j<=n;j++){
if(j==n/2+1) break;
for(auto &i:map1){
if(i.second>=2){
i.second-=2;
ans[n/2+1][j]=i.first;
ans[n/2+1][n-j+1]=i.first;
break;
}
}
}
for(auto &i:map1){
if(i.second>=1){
ans[n/2+1][n/2+1]=i.first;
i.second--;
break;
}
}
for(auto &i:map1){
if(i.second>=1) return false;
}
return true;
}
void f2(LL n,LL r1,LL r2,LL c1,LL c2){
for(LL i=r1;i<=r2;i++){
for(LL j=c1;j<=c2;j++){
ans[i][j]=ans[i][n+1-j];
}
}
}
void f3(LL n,LL r1,LL r2,LL c1,LL c2){
for(LL i=r1;i<=r2;i++){
for(LL j=c1;j<=c2;j++){
ans[i][j]=ans[n+1-i][j];
}
}
}
void f4(LL n,LL r1,LL r2,LL c1,LL c2){
for(LL i=r1;i<=r2;i++){
for(LL j=c1;j<=c2;j++){
ans[i][j]=ans[n+1-i][n+1-j];
}
}
}
void solve1(LL n,bool ok){
for(LL i=1;i<=n;i++){
for(LL j=1;j<=n;j++){
for(auto &k:map1){
if(k.second>=4&&k.second>0){
ans[i][j]=k.first;
k.second-=4;
break;
}
}
}
}
if(ok==1) {
cout<<"YES"<<"\n";
n*=2;
f2(n,1,n/2,n/2+1,n);///右上
f3(n,n/2+1,n,1,n/2);///左下
f4(n,n/2+1,n,n/2+1,n);///右下
}
else if(ok==0){
n*=2;n++;///n=5
f2(n,1,n/2,(n+1)/2+1,n);///右上
f3(n,(n+1)/2+1,n,1,n/2);///左下
f4(n,(n+1)/2+1,n,(n+1)/2+1,n);///右下
if(check2(n)==false){
cout<<"NO"<<"\n";
return;
}
else{
cout<<"YES"<<"\n";
pri(n);
return;
}
}
}
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n;cin>>n;
for(LL i=1;i<=n*n;i++) {cin>>a[i];map1[a[i]]++;}
if(n%2==0){
if( check1()==false ){cout<<"NO"<<"\n";return 0;}
n/=2;
solve1(n,1);
pri(n*2);
}
else if(n&1){
LL temp=n/2;
solve1(temp,0);
}
return 0;
}