题目
过程
思路
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;
}