题意:给你\(n\)个数,判断是否能构成一个\(n\)X\(n\)的回文矩阵,若可以,输出\(YES\)和矩阵,否则输出\(NO\).
题解:如果这个矩阵的行/列元素是偶数的话,很好办,所有出现的数一定是\(4\)的倍数,我们直接判断然后模拟输出一下即可.如果是奇数,就要麻烦一点,我们首先用桶存一下所有元素的出现次数,然后直接模拟,首先奇数矩阵的左上右上左下右下一定是对称的,所以我们可以先看左上角的一个小块,模拟一下,每次可以确定\(4\)个位置.之后就是两行中心线了,除了中心,每个位置的元素的对应位置只有一个,所以判断\(2\)即可,再最后是否剩下一个元素给中心即可.
代码:
int n;
int a[N];
map<int,int> mp;
int g[200][200];
bool st[200][200];
int one;
int main() {
//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
n=read();
for(int i=1;i<=n*n;++i){
a[i]=read();
mp[a[i]]++;
}
if(n%2==0){
bool flag=true;
for(auto w:mp){
if(w.se%4!=0){
flag=false;
break;
}
}
if(!flag) cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
for(auto &w:mp){
for(int i=1;i<=n;++i){
bool flag=true;
for(int j=1;j<=n;++j){
if(!st[i][j]){
g[i][j]=w.fi,st[i][j]=true;
g[i][n+1-j]=w.fi,st[i][n+1-j]=true;
g[n+1-i][j]=w.fi,st[n+1-j][j]=true;
g[n+1-i][n+1-j]=w.fi,st[n+1-i][n+1-j]=true;
w.se-=4;
if(w.se==0){
flag=false;
break;
}
}
}
if(!flag) break;
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cout<<g[i][j]<<" ";
}
cout<<‘\n‘;
}
}
}
else{
int cnt=0;
for(int i=1;i<=n/2;++i){
for(int j=1;j<=n/2;++j){
for(auto &w:mp){
if(w.se>=4){
g[i][j]=w.fi;
g[i][n+1-j]=w.fi;
g[n+1-i][j]=w.fi;
g[n+1-i][n+1-j]=w.fi;
w.se-=4;
cnt++;
break;
}
}
}
}
if(cnt!=(n/2)*(n/2)){
cout<<"NO"<<endl;
return 0;
}
int row=(n/2)+1;
cnt=0;
for(int j=1;j<=n/2;++j){
for(auto &w:mp){
if(w.se>=2){
g[row][j]=w.fi;
g[row][n+1-j]=w.fi;
cnt++;
w.se-=2;
break;
}
}
}
if(cnt!=n/2){
cout<<"NO"<<endl;
return 0;
}
int col=row;
cnt=0;
for(int i=1;i<=n/2;++i){
for(auto &w:mp){
if(w.se>=2){
g[i][col]=w.fi;
g[n+1-i][col]=w.fi;
cnt++;
w.se-=2;
break;
}
}
}
if(cnt!=(n/2)){
cout<<"NO"<<endl;
return 0;
}
for(auto &w:mp){
if(w.se==1){
g[row][col]=w.fi;
cout<<"YES"<<endl;
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
cout<<g[i][j]<<" ";
}
cout<<‘\n‘;
}
return 0;
}
}
cout<<"NO"<<endl;
}
return 0;
}
Codeforces Round #540 (Div. 3) C. Palindromic Matrix (大模拟)
原文:https://www.cnblogs.com/lr599909928/p/13762872.html