B3977 [语言月赛 202405] 更好的交换 题解
ShiRoZeTsu · · 题解
Source & Knowledge
2024 年 5 月语言月赛,由洛谷网校入门计划/基础计划提供。
题目大意
给定一个
题目分析
首先有一个非常显然的暴力,就是直接在每次操作时暴力修改,这样单次操作就是
for(int i = 1, op, x, y; i <= m; i++) {
cin >> op >> x >> y;
if(op == 1) for(int j = 1; j <= n; j++) swap(a[x][j], a[y][j]);
else for(int j = 1; j <= n; j++) swap(a[j][x], a[j][y]);
}
考虑如何优化。不难发现,行和列之间的修改是无关的。我们可以将行和列的操作分开处理。
现在我们假设只有行操作,没有列操作该如何处理。
实际上,我们可以不用真的去交换每一行。考虑用一个数组
if(op == 1) swap(p[x], p[y]);
同理,如果只有列操作,没有行操作,该如何处理呢?可以开一个
if(op == 0) swap(q[x], q[y]);
由于行和列的操作互不相干,所以以上两个方法可以同时进行。也就是说,我们只要用数组 p 和 q 来代替每次的修改就可以了:
for(int i = 1, op, x, y; i <= m; i++) {
cin >> op >> x >> y;
if(op == 1) swap(p[x], p[y]);
else swap(q[x], q[y]);
}
接下来考虑如何输出答案。在用二重循环枚举行和列时,直接输出
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
cout << a[p[i]][q[j]] << ' ';
cout << '\n';
}