洛谷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;
}