top1编程
← 返回题目
题解

八戒偷瓜

1 条题解

  • 0
    @ 2026-8-5 1:11:26

    解题思路

    瓜地是一个 n×n 的方格,每格一个西瓜。八戒每出手一次,偷走以 (x,y) 为左上角的 2×2 共 4 个西瓜,也就是 (x,y)、(x,y+1)、(x+1,y)、(x+1,y+1) 这四格。

    用 bool 数组 taken 标记“被偷过”的格子。注意:

    • 两次出手的 2×2 区域可能重叠,被标记过的格子再标记一次没有关系,反正最后只数一次;
    • 最后遍历整个瓜地,数一数没有被标记的格子,就是还剩下的西瓜数。

    参考代码

    // P4485 八戒偷瓜:每次偷2x2共4个西瓜,求瓜地里剩余的西瓜数
    #include <iostream>
    using namespace std;
    
    bool taken[105][105];   // taken[i][j] 表示第i行第j列的西瓜是否被偷
    
    int main() {
        int n, m;
        cin >> n >> m;
        for (int i = 0; i < m; i++) {
            int x, y;   // 每次偷瓜覆盖的2x2区域的左上角位置
            cin >> x >> y;
            // 标记被偷走的4个西瓜
            taken[x][y] = true;
            taken[x][y + 1] = true;
            taken[x + 1][y] = true;
            taken[x + 1][y + 1] = true;
        }
        int left = 0;   // 剩余西瓜数
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (!taken[i][j]) left++;   // 没有被偷过就算剩余
        cout << left << endl;
        return 0;
    }
    

    复杂度分析

    标记 m 次出手,每次只处理 4 个格子;最后遍历 n×n 个格子。所以时间复杂度 O(m + n²),空间用于标记 O(n²)。

    • 1