1118C-Palindromic Matrix (Thinking + Simulation)

https://codeforces.com/problemset/problem/1118/C


Ideas:

If you draw it, n is an even number, and each number needs to be %4==0.

n is an odd number. Except for the crosshairs, other places must be multiples of 4.

Talk about the details of the simulation.

If the number is even, check each number %4 directly.

If the number is odd, you need to subtract >=4, and then construct a cross line, whether each cross line is >=2 (skip the center point first). Then check it last.

When outputting, it is observed that the other small rectangles are the rotation of the upper left rectangle. Each simulation is thrown into ans[][] and finally the output is judged after the unified check is completed.

#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;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/115268529