Codeforces Round #540 (Div. 3) C. Palindromic Matrix (大模拟)

-
题意:给你\(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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号