题目链接

https://codeforces.com/problemset/problem/1980/E

题意

共输入\(T\)组测试用例,每组测试用例第一行输入两个整数\(n, m\),分别代表输入的数据的行数和列数,其中\(1 \leq T \leq 10^4,n * m \leq 2 * 10^5\)。

接下来输入两个\(n\)行\(m\)列的矩阵\(a, b\),对于每个矩阵中的元素\(x_{i,j}\)都是不同的,且满足:\(1 \leq x_{i,j} \leq n * m\)。

你有以下两种可以执行的操作:

  1. 选择两个不同的行进行交换
  2. 选择两个不同的列进行交换

你可以执行上述操作任意次,每次只能选择其中一个操作。问:能否通过上述操作将矩阵\(b\)变为矩阵\(a\),若能,输出“yes”,否则,输出“no”。

题解

本质是考察线性代数的相等矩阵的知识。

矩阵相等的条件:

  1. 两个矩阵为同型矩阵
  2. 矩阵的元素完全相同

对于条件1,由于矩阵\(a, b\)均为\(n\)行\(m\)列的矩阵,故明显成立

对于条件2,只能使用选择两个不同的行/列进行交换,去尝试使之成立

对于初等行/列变换中的行/列交换,有一个非常重要的性质,就是进行行(列)交换后,行(列)内元素的相对位置不会发生变化

基于上述性质,假设此时发生一次行交换,此时行内的相对顺序是不变的,只是每一列元素的相对位置会发生改变,但是发生改变的仅仅是列内元素的相对位置,原本处于同一列的元素依然会处于同一列。

再假设此时发生一次列交换,此时列内的相对顺序是不变的,只是每一行元素的相对位置会发生改变,但是发生改变的仅仅只是行内元素的相对位置,原本处于同一行的元素依然会处于同一行。

基于上述结论,我们只需要判断出矩阵\(a, b\)的每一行、列各自组成的集合,能否在某个顺序下完全相同即可。若能,则输出“YES”,否则,输出“NO”。

在编码实现上,有个问题就是若直接开一个2e5 * 2e5的矩阵,复杂度必然是不可接受的。

观察题目,已知\(n * m \leq 2e5\),那么不妨直接进行矩阵压缩,将二维矩阵压缩为一维,下面讲解如何将二维矩阵压缩为一维数组:

下图是将\(n\)行\(m\)列的二维矩阵映射成长度为\(n * m\)的一维数组:

观察上图,易知原二维矩阵中,处于同一列的元素,在一维数组中是偏移了长度为\(m\)的长度。在二维矩阵中原本同处于第\(i(1 \leq i \leq n)\)行的元素,在一维数组中是从第\((i - 1) * m + 1\)到第\(i * m\)个元素。

因此,若想在一维数组中遍历二维矩阵的每一行,可以用如下代码:

for (int i = 0; i < n; ++ i) {//共n行
for (int j = 0; j < m; ++ j) {//共m列
//i * m + j
}
}

若想在一维数组中遍历二维矩阵的每一列,可以用如下代码:

for (int i = 0; i < m; ++ i) {//共m列
for (int j = 0; j < n; ++ j) {//共n行
//j * m + i
}
}

参考代码

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std; constexpr int N = 2e5 + 7;
int T, n, m;
int a[N], b[N], row[N], col[N]; void solve() {
cin >> n >> m;
for (int i = 0; i < n * m; ++ i) {
cin >> a[i];
row[a[i]] = i / m;
col[a[i]] = i % m;
}
for (int i = 0; i < n * m; ++ i) cin >> b[i];
if (n == 1 || m == 1) {//行或列等于1时必相等
cout << "YES\n";
return ;
}
//求同行
for (int i = 0; i < n; ++ i) {
int r = row[b[i * m]];
for (int j = 1; j < m; ++ j) {
if (row[b[i * m + j]] != r) {
cout << "NO\n";
return ;
}
}
}
//求同列
for (int i = 0; i < m; ++ i) {
int c = col[b[i]];
for (int j = 1; j < n; ++ j) {
if (col[b[j * m + i]] != c) {
cout << "NO\n";
return ;
}
}
}
cout << "YES\n";
} int main() {
IOS
cin >> T;
while (T --) {
solve();
}
return 0;
}

【矩阵压缩】codeforces 1980 E. Permutation of Rows and Columns的更多相关文章

  1. C++实现矩阵压缩

    C++实现矩阵压缩 转置运算时一种最简单的矩阵运算.对于一个m*n的矩阵M,他的转置矩阵T是一个n*m的矩阵,且T(i,j) = M(j,i). 一个稀疏矩阵的转置矩阵仍然是稀疏矩阵. 矩阵转置 方案 ...

  2. CodeForces 839B - Game of the Rows | Codeforces Round #428 (Div. 2)

    血崩- - /* CodeForces 839B - Game of the Rows [ 贪心,分类讨论] | Codeforces Round #428 (Div. 2) 注意 2 7 2 2 2 ...

  3. [Codeforces 1208D]Restore Permutation (树状数组)

    [Codeforces 1208D]Restore Permutation (树状数组) 题面 有一个长度为n的排列a.对于每个元素i,\(s_i\)表示\(\sum_{j=1,a_j<a_i} ...

  4. 暴力+构造 Codeforces Round #283 (Div. 2) C. Removing Columns

    题目传送门 /* 题意:删除若干行,使得n行字符串成递增排序 暴力+构造:从前往后枚举列,当之前的顺序已经正确时,之后就不用考虑了,这样删列最小 */ /*********************** ...

  5. #467 – 使用UniformGrid 均分行和列(Use a UniformGrid for Evenly Spaced Rows and Columns)

    原文 #467 – 使用UniformGrid 均分行和列(Use a UniformGrid for Evenly Spaced Rows and Columns) UniformGrid 布局面板 ...

  6. CodeForces 483C Diverse Permutation

    Diverse Permutation Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...

  7. [Swust OJ 589]--吃西瓜(三维矩阵压缩)

    题目链接:http://acm.swust.edu.cn/problem/589/ Time limit(ms): 2000 Memory limit(kb): 65535   Description ...

  8. Codeforces 839B Game of the Rows【贪心】

    B. Game of the Rows time limit per test:1 second memory limit per test:256 megabytes input:standard ...

  9. Codeforces 839B Game of the Rows - 贪心

    Daenerys Targaryen has an army consisting of k groups of soldiers, the i-th group contains ai soldie ...

  10. Poj 3318 Matrix Multiplication( 矩阵压缩)

    Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18928   Accepted: ...

随机推荐

  1. DML—对表中的数据进行增删改

    一.添加数据 1.给指定列添加数据 insert into 表名(列名1,列名2,...) values(值1,值2...); 执行给指定列添加数据前: -- 给指定列添加数据 insert into ...

  2. RTThread内对##连接符和#转字符串这俩符号的使用

    早就知道这俩符号的意思,最近翻看代码又看到了,仍然觉得熟悉又陌生,主要是自己平时写代码对这俩符号用的比较少.于是特地做个实验,加深下理解.可记的东西不多,这篇随笔算是随手一写吧. 上实验代码: 来源: ...

  3. MySQL配置缓存查询和维护

    配置文件设置缓存 query_cache_size = 20M #缓存大小 query_cache_type = ON #开启缓存 table_cache=256 #用于限制缓存表的最大数目,如果当前 ...

  4. 原生CSS、HTML 和 JavaScript 实现酷炫表单

    一直使用 Vue/React ,习惯了用组件,偶尔想用原生三剑客写点 Demo 发现样式丑的不忍直视.最近看 掘金小册<玩转CSS的艺术之美>看到 CSS 相关的内容,发现原生 CSS 也 ...

  5. gadget驱动框架(一)

    之前在linux移植udc驱动的时候,没有深入的理解整个gadget驱动框架,现在重新再屡屡gadget驱动,以便后期再次学习.本系列的文章以虚拟串口进行分析,相关源码均是基于linux4.19.12 ...

  6. USB gadget驱动框架(三)

    gadget驱动框架(三) usb_udc与usb_gadget_driver的绑定 usb_udc与usb_gadget_driver,在注册的时候分别被添加到udc_list和gadget_dri ...

  7. 【信创问题】解决东方通(TongWeb)报错 java.lang.NoClassDefFoundError: javax/persistence/spi/PersistenceProvider

    写在前边 今天帮现场同事定位问题,情况是项目同事使用东方通(TongWeb7.0)部署公司项目时,出现以下报错导致服务启动失败. 简单排查了下发现:war包内WEB-INF/lib/javax.per ...

  8. 010 Python 重中之重的变量

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Datatime:2022/7/16 20:32 # Filename:010 Python 重中之重的变 ...

  9. 2.flask 源码解析:应用启动流程

    目录 一.flask 源码解析:应用启动流程 1.1 WSGI 1.2 启动流程 Flask 源码分析完整教程目录:https://www.cnblogs.com/nickchen121/p/1476 ...

  10. 洛谷P1644跳马问题

    跳马问题 题目链接 题目背景 在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧-- 题目描述 中国象棋半张棋盘如图 \(1\) 所示.马自左下角 \((0,0)\) 向右上角 \((m, ...