第26次ccf认证第二题:寻宝!大冒险!
原题链接
参考博客
具体思路见原博主,本文主要提供个人注释
link
代码以及个人理解的注释
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,l,s;
cin>>n>>l>>s;
int tree[n][2]; // 存放所有树的坐标
int Smap[s+1][s+1]; // 存放藏宝图
for (int i=0; i<n; i++){
cin>>tree[i][0]>>tree[i][1];
}
int num = 0; // 藏宝图中树的数量
for (int i=s;i>=0;i--){
for (int j=0;j<=s;j++){
cin>>Smap[i][j];
if (Smap[i][j]==1)
num++;
}
}
int ans = 0;
for (int i=0;i<n;i++){
// 把藏宝图依次和每棵树左下角对齐
int p = tree[i][0], q = tree[i][1];
bool flag = 1; // 默认匹配,通过判断不匹配的情况将flag改写为flase
int temp = 0;
for (int j=0; j<n; j++){
if (tree[j][0]-p>=0 && tree[j][0]-p <=s && tree[j][1]-q>=0 && tree[j][1]-q<=s)
temp++;
}
if (temp == num){ // 如果对齐后藏宝图大小的范围内树的个数
for (int j=0; j<=s; j++){
for (int m=0; m<=s; m++){
if (p+j>l || q+m>l){ // 如果藏宝图当前访问的坐标已经超出绿化图的边界。
flag = 0;
break;
}
if (Smap[j][m]==0){ // 如果藏宝图这里没树,但是绿化图中有,就不可能匹配
for (int k = 0; k<n; k++){
if (tree[k][0] == p+j && tree[k][1] == q+m){
flag = 0;
break;
}
}
}
else {
for (int k=0; k<n; k++){
if (tree[k][0] == p+j && tree[k][1] == q+m) // 如果藏宝图中这里有树(p,q),绿化图中这里也有树,
break;
if (k==n-1) flag = 0; // 访问了所有树的坐标,但都不与当前遍历的藏宝图中的这颗树匹配
}
}
}
}
if (flag) ans++;
}
}
cout<<ans;
return 0;
}