CodeForces-400C 题解

题目传送门

一道模拟题……

先看数据范围,x,y,z109x,y,z \le 10^9 显然会超时。不难看出,顺时针或逆时针旋转 44 次和镜面对称 22 次后会恢复原样,所以我们先对 x,y,zx,y,z 进行取余。

xmod4,zmod4,ymod2x\bmod 4,z\bmod4,y\bmod2

然后我们观察一个矩阵顺时针旋转后坐标的变化,当你在第 xx 行第 yy 列时,旋转后应该在第 yy 行第 nx+1n - x + 1 的位置。即 (x,y)(y,nx+1)(x, y) \to (y, n - x + 1)

接下来观察镜面对称与逆时针旋转,可以分别得出 (x,y)(x,my+1)(x, y) \to (x, m - y + 1)(x,y)(my+1,x)(x, y) \to (m - y + 1, x)

值得注意的是,在顺时针或逆时针旋转后,nnmm 的值需要进行交换,别忘了。

Code

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <bits/stdc++.h>
#define ll long long
#define INF 1e9
using namespace std;
int n, m, x, y, z, p;
int X[100005], Y[100005];
void solve_x() {
for (int i = 1; i <= p; i++) {
int tmp = X[i];
X[i] = Y[i];
Y[i] = n - tmp + 1;
}
swap(n, m); // 交换
}
void solve_y() {
for (int i = 1; i <= p; i++) Y[i] = m - Y[i] + 1;
}
void solve_z() {
for (int i = 1; i <= p; i++) {
int tmp = Y[i];
Y[i] = X[i];
X[i] = m - tmp + 1;
}
swap(n, m); // 交换
}
signed main() {
ios :: sync_with_stdio(0);
cin >> n >> m >> x >> y >> z >> p;
x %= 4, y %= 2, z %= 4; // 注意取模
for (int i = 1; i <= p; i++) cin >> X[i] >> Y[i];
for (int i = 1; i <= x; i++) solve_x();
for (int i = 1; i <= y; i++) solve_y();
for (int i = 1; i <= z; i++) solve_z();
for (int i = 1; i <= p; i++) cout << X[i] << " " << Y[i] << "\n";
return 0;
}

/*
观察过程
1 2 3 7 4 1
4 5 6 -> 8 5 2
7 8 9 9 6 3
(1, 1) -> (1, 3) -> (3, 3) -> (3, 1) -> (1, 1)
……
1 2 3 3 2 1
4 5 6 -> 6 5 4
7 8 9 9 8 7
(1, 1) -> (1, 3) -> (1, 1)
……
1 2 3 3 6 9
4 5 6 -> 2 5 8
7 8 9 1 4 7
(1, 1) -> (3, 1) -> (3, 3) -> (1, 3) -> (1, 1)
……
*/