Hướng dẫn giải của Cắt bảng


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Tác giả: 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;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.