(编程思维\gz -C++提高组)
海淀区第八届“智慧杯”
中小学生计算机程序设计大赛
编程思维赛项( C++提高组)
主办单位:北京市海淀区教育科学研究院
承办单位:网易集团 有道小图灵 1
第1题: 矩阵变换
题目描述
给定一个
行列的矩阵,请输出 次操作后的结果。
每次操作形如:
op x y
其中, 为操作类型, , 为两个整数:
·若 ,则矩阵进行行交换,即:交换 第 行 和 第 行。
·若 ,则矩阵进行列交换,即:交换 第 列 和 第 列。
输入描述
第一行三个整数 ,表示矩阵的行数 ,列数 ,操作次数 。
接下来 行,每行 个整数。
接下来 行,每行三个整数 。
输出描述
输出变换后的矩阵。
样例1
输入
输出
样例2 输入
输出
1 5 3
1 2 3 4 5
1 1 2
1 2 3
1 4 5
1 2 3 4 5
2 3 1 5 41
3 4 2
1 2 3 4
5 6 7 8
9 10 11 12
0 1 3
1 2 4
1 2 3 4 5 6
9 12 11 10
5 8 7 6
1 4 3 21 2 3
(编程思维\gz - C++提高组) 2
数据范围
对于
%的数据, ;
对于 %的数据, , ;
对于 %的数据, , 。
注: 为或者为 ,
,
保证合法。
解析
按题目要求进行模拟,进行矩阵行交换和矩阵列交换。最多进行 次交换,矩阵最大为 ,如
果每次遍历交换,总的时间复杂度为 ,会导致 ,所以模拟只能解决前 的数据。
正解是:每次都进行交换不可以,那我们通过一个映射记录交换的结果,不需要真的执行交换过程。我
们可以用一个数组初始化为 , 表示第 行原本存储的就是
第行的值。当 两行发生交换时,只需要让 发生交换,交换后变为
。同理用一个 数组映射列之间的交换。
最后输出结果时,输出 (,为行和列的映射数组,即经过若干次交换后实际当前应该为
原本的第几行、第几列)。
标程 100%
#include <bits/stdc++.h>
using namespace std;
int a[1005][1005], n, m, k, l, op, x, y, b[1005], c[1005];
int main() {
cin >> n >> m >> k;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j ++) {
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++) b[i] = i;
for(int j = 1; j <= m; j ++) c[j] = j;
while(k --) {
cin >> op >> x >> y;
if(op == 0) swap(b[x], b[y]);
else swap(c[x], c[y]);
}
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= m; j ++) {
cout << a[b[i]][c[j]] << " ";
}
cout << '\n';
}
return 0;
}
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
(编程思维\gz -C++提高组) P
测试
2024年北京海淀区第八届“智慧杯”编程思维-C++提高组题目及题解