洛谷P1789 【Mc生存】插火把 题解 二维数组/模拟

题目链接:https://www.luogu.com.cn/problem/P1789

解题思路:

开一个 \(n \times n\) 的 bool 类型的二维数组 \(a\),一开始 \(a\) 中所有的元素都为 false。
然后根据给我们的坐标和类型(火把或萤石)点亮相应的位置。最后统计有多少个点没有被点亮(为 false)即可。

我们假设 \((x,y)\) 为火把的位置,那么判断一个点 \((x',y')\) 是否在火把照亮范围内的规则可以是:

  • 首先它在地图中,即 \(1 \le x',y' \le n\)
  • 其次 \(|x-x'|+|y-y'| \le 2\)

我们假设 \((x,y)\) 为萤石的位置,那么判断一个点 \((x',y')\) 是否在萤石照亮范围内的规则可以是:

  • 首先它在地图中,即 \(1 \le x',y' \le n\)
  • 其次 \(|x-x'| \le 2\)\(|y-y'| \le 2\)

示例代码如下:

#include <bits/stdc++.h>
using namespace std;
bool a[101][101];
int n, m, k, x, y;
int main() {
    cin >> n >> m >> k;
    while (m --) {  // m把火把
        cin >> x >> y;
        for (int i = -2; i <= 2; i ++) {
            for (int j = -2; j <= 2; j ++) {
                if (1 <= x+i && x+i <= n && 1 <= y+j && y+j <= n && abs(i)+abs(j) <= 2) // 判断是否在火把照亮范围内
                    a[x+i][y+j] = true;
            }
        }
    }
    while (k --) {
        cin >> x >> y;
        for (int i = -2; i <= 2; i ++) {
            for (int j = -2; j <= 2; j ++) {
                if (1 <= x+i && x+i <= n && 1 <= y+j && y+j <= n)
                    a[x+i][y+j] = true;
            }
        }
    }
    int cnt = 0;    // 由于记录有多少地方没有被照亮
    for (int i = 1; i <= n; i ++)
        for (int j = 1; j <= n; j ++)
            if (!a[i][j])
                cnt ++;
    cout << cnt << endl;
    return 0;
}
posted @ 2020-04-24 17:53  quanjun  阅读(335)  评论(0编辑  收藏  举报