Inna and Huge Candy Matrix 题解

发布时间 2023-05-05 22:44:26作者: xvl

题目传送门

一道模拟题。

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

\[x\bmod 4,z\bmod4,y\bmod2 \]

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

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

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

Code

#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)
……
*/