← 返回题目页

A1789 [USACO24DEC] Farmer John's Cheese Block B

标程

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

// [USACO24DEC] Farmer John's Cheese Block B
//
// 关键观察:砖块是 1x1xN,而奶酪块的边长正好也是 N。
// 所以砖块沿某个轴放下去时,一定横跨整个奶酪块,占满那个轴上的一整条「线」
// (N 个格子)。
// 要让砖块不与剩下的奶酪重叠,这条线上的 N 个格子就必须**全部被切掉**。
// 于是答案 = 已经被切空的线的条数。
//
// 维护三个 N*N 的计数数组:
//   gz[x][y]:沿 z 方向的线(固定 x,y)上被切了多少格
//   gy[x][z]:沿 y 方向的线(固定 x,z)上被切了多少格
//   gx[y][z]:沿 x 方向的线(固定 y,z)上被切了多少格
// 每切掉一个格子,这三条线的计数各加 1;某个计数刚好达到 N,说明这条线被切空,
// 答案加 1。

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, Q;
    cin >> N >> Q;

    const size_t M = (size_t)N * N;
    vector<int> gz(M, 0);  // 行=x, 列=y,沿 z 方向的线
    vector<int> gy(M, 0);  // 行=x, 列=z,沿 y 方向的线
    vector<int> gx(M, 0);  // 行=y, 列=z,沿 x 方向的线

    long long ans = 0;
    for (int i = 0; i < Q; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        if (++gz[(size_t)x * N + y] == N) ans++;
        if (++gy[(size_t)x * N + z] == N) ans++;
        if (++gx[(size_t)y * N + z] == N) ans++;
        cout << ans << "\n";
    }
    return 0;
}

动画演示