Editorial for Cắt bảng


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: xuanquang1999

Trong lời giải này, các cột và các dòng được đánh số từ ~0~.

Nhận xét rằng:

  • Phép cắt dọc giữa cột ~y~ và ~y+1~ thật chất là phép xoay theo vòng tròn các cột của bảng về bên phải ~y~ ô (ta xem cột ~m~ nằm bên trái cột ~1~). Nói cách khác, ô ~(i, j)~ sẽ trở thành ô ~(i, (j+y) \bmod m)~.
  • Phép cắt ngang giữa dòng ~x~ và ~x+1~ thật chất là phép xoay theo vòng tròn các dòng của bảng về bên dưới ~y~ ô (ta xem dòng ~n~ nằm bên trên cột ~1~). Nói cách khác, ô ~(i, j)~ sẽ trở thành ô ~((i+x) \bmod n, j)~.

Với nhận xét trên, từ bảng ~a~ ban đầu, bản nhận được chỉ có thể là bảng $a$ sau khi xoay theo vòng tròn về bên phải ~d_y~ ô và xoay theo vòng tròn về bên dưới ~d_x~ ô (với ~0 \le d_x < n~, ~0 \le d_y < m~). Do đó, ta cần kiểm tra xem có tồn tại cặp giá trị ~(d_x, d_y)~ nào mà sau khi xoay thì bảng ~a~ trở thành bảng ~b~ hay không.

Độ phức tạp: ~O(n^2 \times m^2)~.

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;

void solve() {
    int n, m;
    cin >> n >> m;

    vector<vector<int>> a(n, vector<int>(m, 0));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            cin >> a[i][j];
        }
    }

    vector<vector<int>> b(n, vector<int>(m, 0));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            cin >> b[i][j];
        }
    }

    for(int dx = 0; dx < n; ++dx) {
        for(int dy = 0; dy < m; ++dy) {
            bool ok = true;
            for(int i = 0; i < n; ++i) {
                for(int j = 0; j < m; ++j) {
                    if (a[i][j] != b[(i+dx)%n][(j+dy)%m]) {
                        ok = false;
                    }
                }
            }
            if (ok) {
                puts("YES");
                return;
            }
        }
    }

    puts("NO");
}

int main() {
    int t; cin >> t;
    while (t--) solve();

    return 0;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.