CSP 寻宝!大冒险! C++
思路:遍历绿化图的每个树,先判断藏宝图里树的数量和当前树的右上边长为s的正方形的树的数量是否一致,如果一致,再循环遍历判断是否相等。
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, l, s;
cin >> n >> l >> s;
int A[n][2];//绿化图
int B[s + 1][s + 1];//藏宝图
for (int i = 0; i < n; i++) {
cin >> A[i][0] >> A[i][1];
}
int num = 0;//藏宝图树的数量
for (int i = s; i >= 0; i--) {
for (int j = 0; j <= s; j++) {
cin >> B[i][j];
if (B[i][j] == 1) {
num++;
}
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
int p = A[i][0], q = A[i][1];
bool flag = true;
int temp = 0;//这个点的右上边长为s的正方形的树的数量
//锁定藏宝图(很小区域)中的1的个数,用二维前缀和在O(1)时间内查询到以该顶点为左下角的藏宝图中的树木个数如果匹配,再一一遍历。
for (int j = 0; j < n; j++) {
if (A[j][0] - p >= 0 && A[j][0] - p <= s && A[j][1] - q >= 0 && A[j][1] - q <= s) {
temp++;
}
}
if (temp == num) {
for (int j = 0; j < s + 1; j++) {
for (int m = 0; m < s + 1; m++) {
if (p + j > l || q + m > l) {//藏宝图范围超出绿化图的范围
flag = false;
break;
}
if (B[j][m] == 0) {//如果该位置没有树
for (int k = 0; k < n; k++) {
if (A[k][0] == p + j && A[k][1] == q + m) {
flag = false;
break;
}
}
} else {//有树
for (int k = 0; k < n; k++) {
if (A[k][0] == p + j && A[k][1] == q + m)
break;
if (k == n - 1) {
flag = false;
}
}
}
}
}
if (flag) {
ans++;
}
}
}
cout << ans;
}