一、题目:
【Mc生存】插火把
题目描述
话说有一天 linyorson 在“我的世界”开了一个 $n \times n$ 的方阵,现在他有 $m$ 个火把和 $k$ 个萤石,分别放在 $(x_1, y_1) \sim (x_m, y_m)$ 和 $(o_1, p_1) \sim (o_k, p_k)$ 的位置,没有光并且没放东西的地方会生成怪物。请问在这个方阵中有几个点会生成怪物?
P.S. 火把的照亮范围是:
|暗|暗| 光 |暗|暗|
|暗|光| 光 |光|暗|
|光|光|火把|光|光|
|暗|光| 光 |光|暗|
|暗|暗| 光 |暗|暗|
萤石:
|光|光| 光 |光|光|
|光|光| 光 |光|光|
|光|光|萤石|光|光|
|光|光| 光 |光|光|
|光|光| 光 |光|光|
输入格式
输入共 $m + k + 1$ 行。
第一行为 $n, m, k$。
第 $2$ 到第 $m + 1$ 行分别是火把的位置 $x_i, y_i$。
第 $m + 2$ 到第 $m + k + 1$ 行分别是萤石的位置 $o_i, p_i$。
注:可能没有萤石,但一定有火把。
输出格式
有几个点会生出怪物。
样例 #1
样例输入 #1
5 1 0
3 3
样例输出 #1
12
提示
数据保证,$1 \le n \le 100$,$1 \leq m+k \leq 25$,$1 \leq m \leq 25$,$0 \leq k \leq 5$。
二、思路:
题目简单,但是在看题解是看到了一个令人我眼前一亮的防止数组越界的函数写法,后模仿着解了题,也是第一次用“增量数组”,特此记录学习:该函数如下:
int s(int t) {
if (t > 0)
return t;
return 0;
}三、源码:
#include <iostream>
#include <string.h>
using namespace std;
int x1[] = {0, -2, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 2};
int y11[] = {0, 0, -1, 0, 1, -2, -1, 0, 1, 2, -1, 0, 1, 0};//竟然有名为“y1”的内置函数
int x2[] = {0, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
int y2[] = {0, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2};
//累
int s(int t) {
if (t > 0)
return t;
return 0;
}
int n, m, k, x, y;
int arr[1005][1005];//注意写外边,不然爆栈了
int main() {
cin >> n >> m >> k;
memset(arr, 0, sizeof(arr));
for (int times = 1; times <= m; times++) {
cin >> x >> y;
for (int j = 1; j <= 13; j++) {
arr[s(x + x1[j])][s(y + y11[j])] = 1;
}
}
for (int times = 1; times <= k; times++) {
cin >> x >> y;
for (int j = 1; j <= 26; j++) {
arr[s(x + x2[j])][s(y + y2[j])] = 1;
}
}
int count = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (arr[i][j] == 0) {
count++;
}
}
}
cout << count;
return 0;//好习惯(强调!)
}欢迎改正与补充