CCF 202206-2 寻宝!大冒险!(C++)
题目三个要点:
- 藏宝图和绿化图对应的部分的树木数是一样的。
- 在1的前提下,只用遍历藏宝图的有树木的坐标看绿化图中是否有对应的。
- 藏宝图在左下角对应绿化图某个坐标的时候,剩下藏宝图不要超出绿化图界限。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
// green是绿化图中树的坐标
int green[1005][2];
// treasure是藏宝图的01矩阵
int treasure[51][51];
int main()
{
int n, l, s;
scanf("%d %d %d", &n, &l, &s);
for (int i = 0; i < n; i++){
scanf("%d %d", &green[i][0], &green[i][1]);
}
int num = 0; // 树的数量
for (int i = 0; i < s+1; i++){
for (int j = 0; j < s+1; j++){
scanf("%d", &treasure[s-i][j]);
if (treasure[s-i][j]==1)
num++;
}
}
int ant = 0;
for (int i = 0; i < n; i++){
if (green[i][0]<=l-s&&green[i][1]<=l-s){ //判断藏宝图对准该坐标是否超出位置(l-s)是为了防止爆掉
int x = green[i][0];
int y = green[i][1];
// 判断树的数目对不对的上,该预处理是为了减少运行时间
int temp = 0;
for (int j = 0; j < n; j++){
if (green[j][0]>=x&&green[j][0]-s<=x&&green[j][1]>=y&&green[j][1]-s<=y){
temp++;
}
}
if (temp != num){
continue;
}
//遍历藏宝图的有树木的坐标看绿化图中是否有对应的
bool flag = true;
for (int j = 0; j < s+1; j++){
for (int k = 0; k < s+1; k++){
if (treasure[j][k]==1){
bool in = false;
for (int m = 0; m < n; m++){
if (green[m][0]==j+x&&green[m][1]==k+y){
in = true;
break;
}
}
if (in == false){
flag = false;
break;
}
}
}
if (flag == false){
break;
}
}
if (flag == true){
ant++;
}
}
}
printf("%d", ant);
return 0;
}