热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

检查给定的数组元素是否可以形成回文矩阵

检查给定的数组元素是否可以形成回文矩阵原文:https://www . geesforgeks . org/check-if-a

检查给定的数组元素是否可以形成回文矩阵

原文:https://www . geesforgeks . org/check-if-a-回文-矩阵-可以从给定的数组元素中形成/

给定一个由 N 2 个整数组成的数组arr【】】,任务是检查是否可以由给定的数组元素形成维度为 N * N 的矩阵,即回文。如果可能,打印回文矩阵。

一个回文矩阵就是每一行每一列都是回文的矩阵。

示例:

输入: arr[] = {5,1,3,4,5,3,5,4,5}
输出:

5 3 5
4 1 4
5 3 5

输入: arr[] = {3,4,2,1,5,6,6,9}
输出:

方法:下面是一些观察结果,根据这些观察结果可以解决给定的问题:


  • 这里的一个重要观察是–要将值放在第一行的第一列,需要将完全相同的值放在同一行的最后一列,以保留该行的回文行为。此外,要使列回文,需要将相同的值放在最后一行的第一列和最后一列。

  • 因此,总共需要 4 个相同值的实例才能将它们对称地放入矩阵中。

  • 同样,在具有奇数行和列的矩阵的情况下,中间的行和列只需要相同值的两个实例,因为中间的行和列中的元素将是自身对称的。

  • 所以这里的元素可以分为三种类型:

    1. 频率为 4 的倍数的元素。

    2. 频率为 2 的倍数的元素。

    3. 只出现一次的元素。



现在使用贪婪技术按照以下步骤填充矩阵:


  1. 使用优先级队列以排序的方式存储元素的频率。

  2. 如果当前行不是中间行,则选择一个频率至少为4的元素,将这些 4 号对称地放置在四个角上,使得放置它的行和列保持回文状态。

  3. 如果当前行是中间行,选择一个频率为至少为 2 的元素,对称放置这些值。

  4. 如果在任何步骤中没有找到所需数量的元素,则回文矩阵是不可能的,然后打印

  5. 否则,打印并打印形成的回文矩阵。

下面是上述方法的实现:

C++14


// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to fill the matrix to
// make it palindromic if possible
void fill(vector<pair<int, int> >& temp,
          priority_queue<pair<int, int> >& q,
          vector<vector<int> >& 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<int, int> mp;
    // Stores in the order of frequency
    priority_queue<pair<int, int> > q;
    // To store the palindromic
    // matrix if exists
    vector<vector<int> >
    grid(N, vector<int>(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<pair<int, int> > 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;
}

Output:

Yes
1 4 1
3 2 3
1 4 1

时间复杂度:O(N2)
辅助空间: O(N 2 )


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 一、什么是闭包?有什么作用什么是闭包闭包是定义在一个函数内部的函数,它可以访问父级函数的内部变量。当一个闭包被创建时,会关联一个作用域—— ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
author-avatar
小马哥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有