题解
题目大意,给你n*n个数值,要求构造一个n阶对称方阵,方阵上下对称左右对称沿主对角线对称。
根据题目所给示例可以发现,n为偶数情况每个数值至少出现4次,n为奇数情况行坐标或列坐标为(n+1)/2时数值最少出现两次(标号从1开始),最中心位置数值最少出现一次。
根据规律进行构造即可。
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
#define fst first
#define sed second
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int N = 1010;
int a[N], k;
int g[50][50];
int num(int cnt) //得到出现cnt次的数
{
while (k <= 1000 && a[k] < cnt)
k++;
if (k > 1000)
cout << "NO" << endl, exit(0);
a[k] -= cnt;
return k;
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int n;
cin >> n;
for (int i = 1; i <= n * n; i++)
{
int x;
scanf("%d", &x);
a[x]++;
}
k = 1;
for (int i = 1; i <= n / 2; i++) //4次
for (int j = 1; j <= n / 2; j++)
g[i][j] = g[n - i + 1][j] = g[i][n - j + 1] = g[n - i + 1][n - j + 1] = num(4);
if (n & 1)
{
k = 1;
for (int i = 1; i <= n / 2; i++) //2次
if (i != (n + 1) / 2)
{
g[i][(n + 1) / 2] = g[n - i + 1][(n + 1) / 2] = num(2);
g[(n + 1) / 2][i] = g[(n + 1) / 2][n - i + 1] = num(2);
}
k = 1;
g[(n + 1) / 2][(n + 1) / 2] = num(1);//1次
}
cout << "YES" << endl;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
printf("%d ", g[i][j]);
cout << endl;
}
return 0;
}