Hướng dẫn giải của Bedao Grand Contest 15 - Bacteria


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.

Ta có thể thấy rằng ban đầu viền ngoài của khay không có vi khuẩn thì qua một ngày thì số vi khuẩn ở trên viền chính là số vi khuẩn ở vòng trong. Lấy ví dụ là viền trên, ta có ~a_{2,j}=b_{1,j}~ ~(1 \le j \le m)~ do ô ~(1,j)~ bị ảnh hưởng bởi hai ô kề ngang và một ô kề dưới, mà hai ô kề ngang ban đầu là không có nên chỉ có ô dưới thôi. Cách lập luận tương tự cho viền trái, phải, dưới. Ta có thể tưởng tượng cái khay giống như hành tây có nhiều vòng vậy, xác định từng vòng từ ngoài vào trong. Sau đó những ô trong vòng 2 loại bỏ ảnh hưởng của vòng 1 và chính trong vòng đó, lấy ví dụ là viền trên của vòng thứ 2, ta có ~b_{2,j}-a_{2,j-1}-a_{2,j+1}-a_{1,j}~ chính là giá trị của ~a_{3,j}~. Ta làm tương tự như vậy cho từng vòng từ ngoài vào trong là ra đáp án.

Độ phức tạp: ~\mathcal O(nm)~.

#include <bits/stdc++.h>
using namespace std;

const int SZ = 107;

int n, m;
int b[SZ][SZ], a[SZ][SZ];

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

void print() {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            cout << a[i][j] << (j + 1 < m ? " " : "\n");
        }
}

void solve() {
    int nLayer = (min(n, m) + 1) >> 1;
    for (int layer = 1; layer < nLayer; layer++) {
        int nrow = n - (layer << 1), ncol = m - (layer << 1);
        int opp_row = n - layer - 1, opp_col = m - layer - 1;
        // Get from the outside
        for (int i = 0; i < nrow; i++) {
            int x = i + layer;
            a[x][layer] = b[x][layer - 1];
            a[x][opp_col] = b[x][opp_col + 1];
        }
        for (int j = 0; j < ncol; j++) {
            int y = j + layer;
            a[layer][y] = b[layer - 1][y];
            a[opp_row][y] = b[opp_row + 1][y];
        }
        // Update the ring
        for (int i = 0; i < nrow; i++) {
            int x = i + layer;
            b[x][layer] -= a[x - 1][layer] + a[x + 1][layer] + a[x][layer - 1];
            b[x][opp_col] -=
                a[x - 1][opp_col] + a[x + 1][opp_col] + a[x][opp_col + 1];
        }
        for (int j = 0; j < ncol; j++) {
            int y = j + layer;
            b[layer][y] -= a[layer][y - 1] + a[layer][y + 1] + a[layer - 1][y];
            b[opp_row][y] -=
                a[opp_row][y - 1] + a[opp_row][y + 1] + a[opp_row + 1][y];
        }
    }
}

int main() {
    read();
    solve();
    print();
    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.