题目
过程
思路
1.绿化图坐标边界太大,不能直接用矩阵表示,可以用一个二维数组存储有树坐标的x,y值。
定义两个数组:绿化图arr[1005][2]、宝藏图数组b[55][55]
2.
依据条件,从绿化图中第一棵树的坐标开始区域遍历。统计绿化图与藏宝图中一一对应的树的棵数sum,在进行区域比对前,判断该区域树的数量是否等于sum,不等的话直接跳过该区域。
3.将绿化图中的每一棵树的坐标(x,y)作为(0,0)点,其它树的坐标(xx,yy)对应藏宝图中坐标(xx-x,yy-y)。
4.接着遍历藏宝图中每一个点,根据是否有树进行讨论判断。使用flag标记是否舍弃当前区域(1舍弃,0保留),分为以下三种情况讨论:
1.藏宝图范围超出绿化图范围,舍弃。
2.原宝藏图位置[j][k]没有树,从绿化图位置计算[j][k]有树,推测情况与真实情况不符,舍弃。
3.原宝藏图位置[j][k]有树,从绿化图位置计算[j][k]有树,推测情况与真实情况相符,保留;遍历完绿化图都没有找到树,舍弃。
参考:http://t.csdnimg.cn/wZw8m
代码
#include<bits/stdc++.h>
using namespace std;
int arr[1005][2]; //记录树的坐标
int b[55][55]; //藏宝图矩阵
int main()
{
int n,L,S;
int sum=0; //记录藏宝图中树的棵数
cin>>n>>L>>S;
//输入树的坐标
for(int i=0;i<n;i++) cin>>arr[i][0]>>arr[i][1];
//输入藏宝图
for(int i=S;i>=0;i--)
{
for(int j=0;j<=S;j++)
{
cin>>b[i][j]; //注意先输入b[s][0]
if(b[i][j]==1) sum++;
}
}
int num=0; //符合的坐标数
for(int i=0;i<n;i++)
{
int x=arr[i][0];
int y=arr[i][1];
int t=0; //记录当前区域中树的棵树
for(int j=0;j<n;j++)
{
int xx=arr[j][0];
int yy=arr[j][1];
//假设藏宝图在当前区域,统计当前区域中绿化图树与藏宝图中树一一对应棵数
//该预处理减少运行时间
if((xx-x>=0)&&(xx-x<=S)&&(yy-y>=0)&&(yy-y<=S)&&b[xx-x][yy-y]==1)
{
t++;
}
}
if(t==sum) //只有当前区域树的数量等于藏宝图中树的数量才需要考虑
{
int flag=0; //标记位
//遍历藏宝图的树木坐标看绿化图中是否有对应
for(int j=0;j<=S;j++)
{
for(int k=0;k<=S;k++)
{
if (x + j > L || y + k > L) //藏宝图范围超出绿化图的范围
{
flag = 1;
break;
}
if(b[j][k]==0) //宝藏图[j][k]没有树
{
for(int m=0;m<n;m++)
{
int xx=arr[m][0];
int yy=arr[m][1];
if(xx-x==j&&yy-y==k) //从绿化图推测[j][k]有树,与真实宝藏图矛盾
{
flag=1;
break;
}
}
}
else //宝藏图[j][k]有树
{
for(int m=0;m<n;m++)
{
int xx=arr[m][0];
int yy=arr[m][1];
if(xx-x==j&&yy-y==k)//从绿化图推测[j][k]有树
{
break;
}
if(m==n-1) //没有找到树
{
flag=1;
break;
}
}
}
if(flag==1) break;
}
if(flag==1) break;
}
if(flag==0)
{
num++;
}
}
}
cout<<num;
return 0;
}