codeforces 1118C
矩阵是否中心对称
偶数直接判断每个数的个数是否恰为4的倍数
奇数,计算余为1和3的个数,有且仅有一个才可能成为中心。余为2的个数不因大于N - 1(减去中心)
#include<bits/stdc++.h>
using namespace std;
#define fst first
#define sec second
#define sci(num) scanf("%d",&num)
#define scl(num) scanf("%lld",&num)
#define mem(a,b) memset(a,b,sizeof a)
#define cpy(a,b) memcopy(a,b,sizeof b)
typedef long long LL;
typedef pair<int,int> P;
const int MAX_N = 1e5 + 100;
const int MAX_M = 310;
int mtx[410][410];
int a[1010];
struct e{
int num,cnt;
bool operator<(e& e1) {
if (this->cnt != e1.cnt ) return this->cnt > e1.cnt ;
return this->num < e1.num;
}
} e[1010];
int main() {
ios::sync_with_stdio(false); cin.tie(0);
int N;
cin >> N;
for (int i = 1;i <= 1000;i++)
e[i].num = i;
for (int i = 1;i <= N * N;i++) {
cin >> a[i];
e[a[i]].cnt++;
}
if (N == 1) {
cout << "YES" << endl;
cout << a[1] << endl;
} else {
sort(e + 1,e + 1001);
int cnt = 1;
for (;e[cnt].cnt;cnt++)
;
cnt--;
int len = N;
if (len % 2 == 1) {
bool flag = true;
int cnt1 = 0; int loc = -1;
int cnt2 = 0;
int cnt3 = 0;
for (int i = 1;i <= cnt;i++) {
if (e[i].cnt % 4 == 1) {
cnt1++;
loc = i;
} else if (e[i].cnt % 4 == 2) {
cnt2++;
} else if (e[i].cnt % 4 == 3) {
cnt3++;
loc = i;
}
}
int cnt4 = cnt - cnt1 - cnt2 - cnt3;
if (cnt1 + cnt3 != 1) flag =false;
mtx[len/2+1][len/2+1] = e[loc].num;
e[loc].cnt--;
if (cnt1 == 1) cnt1--,cnt4++;
else if (cnt3 == 1) cnt3--,cnt2++;
if (cnt2 > len - 1 || cnt2 % 2 == 1) flag = false;
if (!flag) {
cout << "NO" << endl;
return 0;
}
int now = 1;
for (int i = 1;i <= len / 2;i++) {
for (int j = 1;j <= len / 2;j++) {
while (e[now].cnt < 4) now++;
mtx[i][j] = mtx[i][len - j + 1]
= mtx[len - i + 1][j] = mtx[len - i + 1][len - j + 1] = e[now].num;
e[now].cnt -= 4;
}
}
int t = 1;
for (int i = 1;i <= len / 2;i++) {
int j = len / 2 + 1;
while (e[t].cnt == 0) t++;
mtx[i][j] = mtx[len - i + 1][j] = e[t].num;
e[t].cnt -= 2;
while (e[t].cnt == 0) t++;
mtx[j][len - i + 1] = mtx[j][i] = e[t].num;
e[t].cnt -= 2;
}
} else {
bool flag = true;
for (int i = 1;i <= cnt;i++) {
if (e[i].cnt % 4 != 0) {
flag = false;
}
}
if (!flag) {
cout << "NO" << endl;
return 0;
}
int now = 1;
for (int i = 1;i <= len / 2;i++) {
for (int j = 1;j <= len / 2;j++) {
while (e[now].cnt== 0) now++;
mtx[i][j] = mtx[i][len - j + 1]
= mtx[len - i + 1][j] = mtx[len - i + 1][len - j + 1] = e[now].num;
e[now].cnt -= 4;
}
}
}
cout << "YES" << endl;
for (int i = 1;i <= len;i++) {
cout << mtx[i][1];
for (int j = 2;j <= len;j++) {
cout << " " << mtx[i][j];
}
cout << endl;
}
}
return 0;
}