codeforces1118c

C. Palindromic Matrix

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Let's call some square matrix with integer values in its cells palindromic if it doesn't change after the order of rows is reversed and it doesn't change after the order of columns is reversed.

For example, the following matrices are palindromic:

The following matrices are not palindromic because they change after the order of rows is reversed:

The following matrices are not palindromic because they change after the order of columns is reversed:

You are given n2n2 integers. Put them into a matrix of nn rows and nn columns so that each number is used exactly once, each cell contains exactly one number and the resulting matrix is palindromic. If there are multiple answers, print any. If there is no solution, print "NO".

Input

The first line contains one integer nn (1≤n≤201≤n≤20).

The second line contains n2n2 integers a1,a2,…,an2a1,a2,…,an2 (1≤ai≤10001≤ai≤1000) — the numbers to put into a matrix of nn rows and nncolumns.

Output

If it is possible to put all of the n2n2 numbers into a matrix of nn rows and nn columns so that each number is used exactly once, each cell contains exactly one number and the resulting matrix is palindromic, then print "YES". Then print nn lines with nn space-separated numbers — the resulting matrix.

If it's impossible to construct any matrix, then print "NO".

You can print each letter in any case (upper or lower). For example, "YeS", "no" and "yES" are all acceptable.

Examples

input

Copy

4
1 8 8 1 2 2 2 2 2 2 2 2 1 8 8 1

output

Copy

YES
1 2 2 1
8 2 2 8
8 2 2 8
1 2 2 1

input

Copy

3
1 1 1 1 1 3 3 3 3

output

Copy

YES
1 3 1
3 1 3
1 3 1

input

Copy

4
1 2 1 9 8 4 3 8 8 3 4 8 9 2 1 1

output

Copy

NO

input

Copy

1
10

output

Copy

YES
10 

Note

Note that there exist multiple answers for the first two examples.

题意:

        就是给你n*n个数字,判断是否这n*n个数字是否可以构成一个回文矩阵,如果可以输出“YES”并输出该回文矩阵(任意一个即可),不可以的话就输出“NO”;回文矩阵:即任意一行或者一列在反转之后不改变;

思路:

        考虑到题目要求输出回文矩阵观察了一下给的数字范围并不是很大,我就直接暴力了,即一个空格一个空格的填数字,细心一点应该都可以一发过的;

        我是先统计了一下每个数字出现的次数,然后分偶数和奇数来处理。如果n是奇数的话,先填充四个数字对称的,然后就是中间的一行和一列,最后再把中心的填上即可;如果n是偶数的话相对来说要简单一点,因为它们都是每四个数字成一对对称的;

具体看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using  namespace std;

#define ll long long
const int MAXN = 1000 + 10;
int n,cnt[MAXN],mat[25][25],x;

int main() {

	memset(cnt, 0, sizeof(cnt));
	scanf("%d",&n);
	for (int i = 1; i <= n * n; i++)scanf("%d", &x), cnt[x]++;		//统计次数
	if (n & 1) {				//当n时奇数时
		int mid=n/2+1;			//mid是对称位置
		int k = 1;
		bool success = true;	//判断是否找到了数字填充的数组中
		for (int i = 1; i <= n / 2; i++) {			//填充四个数字成一对对称的
			for (int j = 1; j <= n / 2; j++) {
				success = false;
				for (; k <= 1000; k++) {
					if (cnt[k] >= 4) {
						mat[i][j] = mat[i][mid * 2 - j] = mat[mid * 2 - i][j] = mat[mid * 2 - i][mid * 2 - j] = k;
						cnt[k] -= 4;
						success = true; break;
					}
				}
				if (!success)break;
			}
			if (!success)break;
		}
		if (!success)puts("NO");
		else {
			k = 1;
			for (int i = 1; i < mid; i++) {		//填充中间一行两两对称的
				success = false;
				for (; k <= 1000; k++) {
					if (cnt[k] >= 2) {
						mat[mid][i] = mat[mid][mid * 2 - i] = k;
						cnt[k] -= 2;
						success = true; break;
					}
				}
				if (!success)break;
			}
			if (!success)puts("NO");
			else {
				k = 1;
				for (int i = 1; i < mid; i++) {			//填充中间一列两两对称的
					success = false;
					for (; k <= 1000; k++) {
						if (cnt[k] >= 2) {
							mat[i][mid] = mat[mid*2-i][mid] = k;
							cnt[k] -= 2;
							success = true; break;
						}
					}
					if (!success)break;
				}
				if (!success)puts("NO");
				else {
					success = false;
					for (int i = 1; i <= 1000; i++) {   //填充中心的一个数字
						if (cnt[i] == 1) {
							mat[mid][mid] = i;
							success = true; break;
						}
					}
					if (!success)puts("NO");
					else {
						puts("YES");
						for (int i = 1; i <= n; i++) {
							for (int j = 1; j <= n; j++) {
								printf("%d ",mat[i][j]);
							}
							printf("\n");
						}
					}
				}
			}
		}
	}
	else {                           //n是偶数时
		int k = 1;
		bool success = false;
		for (int i = 1; i <= n / 2; i++) {
			for (int j = 1; j <= n / 2; j++) {
				success = false;
				for (; k <= 1000; k++) {
					if (cnt[k] >= 4) {
						mat[i][j] = mat[i][n + 1 - j] = mat[n + 1 - i][j] = mat[n + 1 - i][n + 1 - j] = k;
						cnt[k] -= 4;
						success = true; break;
					}
				}
				if (!success)break;
			}
			if (!success)break;
		}
		if (!success)puts("NO");
		else {
			puts("YES");
			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					printf("%d ", mat[i][j]);
				}
				printf("\n");
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiaonanxinyi/article/details/87830719