给定一个由N 2个整数组成的数组arr [] ,任务是检查是否可以从给定的数组元素(回文)中形成维度为N * N的矩阵。如果可能,请打印回文矩阵。
A palindrome matrix is the one in which each of the rows and columns are palindrome.
例子:
Input: arr[] = {5, 1, 3, 4, 5, 3, 5, 4, 5}
Output:
Yes
5 3 5
4 1 4
5 3 5
Input: arr[] = {3, 4, 2, 1, 5, 6, 6, 6, 9}
Output: No
方法:以下是可解决给定问题的一些观察结果:
- 这里的一个重要观察结果是–要将值放在第一行的第一列中,需要将相同的值完全放在同一行的最后一列中,以保留该行的回文行为。另外,要使列回文,必须在最后一行的第一列和最后一列中输入相同的值。
- 因此,总共需要4个相同值的实例,以将它们对称地放入矩阵中。
- 同样在矩阵具有奇数行和列的情况下,中间行和列仅需要两个值相同的实例,因为中间行和列中的元素将彼此对称。
- 因此,这里的元素可以分为三种类型:
- 频率为4的倍数的元素。
- 频率为2的倍数的元素。
- 仅存在一次的元素。
现在,使用贪婪技术,通过以下步骤填充矩阵:
- 使用优先级队列以排序的方式存储元素的频率。
- 如果当前行不是中间行,则选择一个频率至少为4的元素,以将这4个数字对称地放置在四个角上,以使放置它的行和列保持回文。
- 如果当前行是中间行,则选择一个频率至少为2的元素以对称地放置这些值。
- 如果在任何步骤都找不到所需数量的元素,则不可能使用回文矩阵,然后打印No。
- 否则,打印“是”并打印形成的回文矩阵。
下面是上述方法的实现:
C++14
// C++ program for the above approach
#include
using namespace std;
// Function to fill the matrix to
// make it palindromic if possible
void fill(vector >& temp,
priority_queue >& q,
vector >& grid)
{
// First element of priority queue
auto it = q.top();
q.pop();
// If the frequency of element is
// less than desired frequency
// then not possible
if (it.first < temp.size()) {
cout << "No\n";
exit(0);
}
// If possible then assign value
// to the matrix
for (auto c : temp) {
grid
= it.second;
}
// Decrease the frequency
it.first -= temp.size();
// Again push inside queue
q.push(it);
}
// Function to check if palindromic
// matrix of dimension N*N can be
// formed or not
void checkPalindrome(int A[], int N)
{
// Stores the frequency
map mp;
// Stores in the order of frequency
priority_queue > q;
// To store the palindromic
// matrix if exists
vector >
grid(N, vector(N));
for (int c = 0; c < N * N; c++) {
mp[A]++;
}
// Number of rows
// Assign in priority queue
for (auto c : mp)
q.push({ c.second, c.first });
// Middle index
int m = N / 2;
// Stores the indexes to be filled
vector > temp;
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
// Find the opposite indexes
// which have same value
int revI = N - i - 1;
int revJ = N - j - 1;
temp = { { i, j },
{ revI, j },
{ i, revJ },
{ revI, revJ } };
// Check if all the indexes
// in temp can be filled
// with same value
fill(temp, q, grid);
temp.clear();
}
}
// If N is odd then to fill the
// middle row and middle column
if (N & 1) {
for (int i = 0; i < m; i++) {
// Fill the temp
temp = { { i, m },
{ N - i - 1, m } };
// Fill grid with temp
fill(temp, q, grid);
// Clear temp
temp.clear();
// Fill the temp
temp = { { m, i },
{ m, N - i - 1 } };
// Fill grid with temp
fill(temp, q, grid);
temp.clear();
}
// For the middle element
// of middle row and column
temp = { { m, m } };
fill(temp, q, grid);
}
cout << "Yes" << endl;
// Print the matrix
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cout << grid[i][j] << " ";
}
cout << endl;
}
}
// Driver Code
int main()
{
// Given array A[]
int A[] = { 1, 1, 1, 1, 2, 3, 3, 4, 4 };
int N = sizeof(A) / sizeof(A[0]);
N = sqrt(N);
// Function call
checkPalindrome(A, N);
return 0;
}
输出:
Yes
1 4 1
3 2 3
1 4 1
时间复杂度: O(N 2 )
辅助空间: O(N 2 )