[构造] aw3732. 矩阵复原(模拟+构造)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[构造] aw3732. 矩阵复原(模拟+构造)相关的知识,希望对你有一定的参考价值。
1. 题目来源
链接:3732. 矩阵复原
2. 题目解析
构造题目,思维具有跳跃性…
又没看清题目,每个数只会出现一次,每行、列的也只会出现一次…
那么针对列而言,可以通过输入中列的首元素确定出其在行中出现的位置,即求得在输入行中的行列所在位置,因为每个数字都是唯一的,所有能够查找出来。且只需要知道列的位置关系即可,假设在第 k
列,那么该列元素就是答案的第 k
列。
比较抽象,看 y总笔记吧:
有一说一,还是得好好读题。本题比较饶,给出的单行、单列中的元素都是按照原数组给出的,但是各行列的顺序发生了变化。
按这个题解,模拟下第一个样例,非常容易帮助理解。
实际上只需要确定一列、或者一行在最终数组中的位置,剩下的就全部确定了,即列的输入,其实只有一列是有效的,其余的完全可以不必读入。
由列确定行所在位置,由行确定列所在位置。秒啊!
个人理解:
但是,这个写法实际上和本题写法实际上的是一致的,本题的写法更加精炼。 但需要注意的是,本题数据量可以给的更少,即给出全部行,只给一列,或者给出全部列,只给一行。 但是整个复杂度是不变,所以这个想法也没啥大用哈哈😆。
时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( n 2 ) O(n^2) O(n2)
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int n, m;
int a[N * N]; // 存每个数所在的列号
int res[N][N];
int main() {
int T; cin >>T; while (T -- ) {
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ ) {
int x;
cin >> x;
a[x] = j;
}
for (int i = 0; i < m; i ++ ) { // 读取每一列
int x;
cin >> x;
int k = a[x]; // 每列的第一个数,找到在行中的对应列号
res[0][k] = x; // 每列第一个数都是第 0 行的
for (int j = 1; j < n; j ++ ) {
int t;
cin >> t;
res[j][k] = t;
}
}
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < m; j ++ )
cout << res[i][j] << ' ';
cout << endl;
}
}
return 0;
}
只用全部行、一列 确定出整个矩阵。
#include <bits/stdc++.h>
using namespace std;
const int N = 505;
int n, m;
int a[N * N], c[N * N]; // 存每个数所在的列号
int b[N][N], col[N];
int res[N][N];
int main() {
int T; cin >>T; while (T -- ) {
cin >> n >> m;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ ) {
int x;
cin >> x;
c[x] = i, a[x] = j; // 行、列
b[i][j] = x;
}
// 只读一列
for (int i = 0; i < n; i ++ ) cin >> col[i];
// 后面 m-1 列读空即可
for (int i = 1; i < m; i ++ )
for (int i = 0; i < n; i ++ ) {
int x;
cin >> x;
}
// 通过第一列中的元素出现顺序,得到该元素所在原数组行的位置
// 元素唯一,确定出这一行的所有元素
// 将其写到答案数组中
for (int i = 0; i < n; i ++ ) {
int x = i; // 元素在列中所在位置即为行,在行中所在位置即为列
int t = c[col[i]]; // 行中哪一行
// 答案写入,在此可以直接输出。因为列确定行,列是按下标走的,是按第 0,1,2,..,n 行进行确定的
// for (int i = 0; i < m; i ++ ) res[x][i] = b[t][i];
for (int i = 0; i < m; i ++ ) cout << b[t][i] << ' ';
cout << endl;
}
/*
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < m; j ++ )
cout << res[i][j] << ' ';
cout << endl;
}
*/
}
return 0;
}
以上是关于[构造] aw3732. 矩阵复原(模拟+构造)的主要内容,如果未能解决你的问题,请参考以下文章
[构造] aw3762. 二进制矩阵(困难模拟+分类讨论+简化代码+思维)