题目
试题编号 | 202206-2 |
---|---|
试题名称 | 寻宝!大冒险! |
时间限制 | 0.5s |
内存限制 | 512MB |
问题描述 | |
输入输出 | |
样例1 | |
样例2 | |
限制 |
题目分析
题目意思是给一个
(
L
+
1
)
∗
(
L
+
1
)
(L+1)*(L+1)
(L+1)∗(L+1)大小的地图,上面有n个树设置为1,其余的点是0。然后给一个
(
S
+
1
)
∗
(
S
+
1
)
(S+1)*(S+1)
(S+1)∗(S+1)的小地图,问你这块小地图可以和大地图中的哪些块完全吻合。吻合的意思是小地图中的0和1的个数,位置相对于大地图中的子块是完全一致的。题目限制小地图左下角一定是一棵树,即1.所以就要从大地图中的每棵树,也就是1的位置开始看当前子块是不是和小地图完全一样。形式化说就是:
子图是
b
[
s
+
1
]
[
s
+
1
]
b[s+1][s+1]
b[s+1][s+1]。如果大地图中
a
[
x
]
[
y
]
=
1
a[x][y]=1
a[x][y]=1。那么就看是不是有
a
[
x
+
_
x
]
[
y
+
_
y
]
=
b
[
_
x
]
[
_
y
]
a[x+\_x][y+\_y]=b[\_x][\_y]
a[x+_x][y+_y]=b[_x][_y]
如果对于
_
x
,
_
y
∈
[
0
,
s
]
\_x,\_y \in[0,s]
_x,_y∈[0,s]都成立,那么就说大地图中的这棵树可能是含有宝藏的,最终答案+1。
解答思路
我的思路很暴力:
- 先把所有的大地图中的1的位置(x,y)记录在一个集合q中,再把小地图中的1位置 ( _ x , _ y ) (\_x,\_y) (_x,_y)记录在另一个集合qq中。
- 遍历q中的每一棵树(x,y),查询其周围地图 g [ x ] [ y ] = ( x + i , y + j ) ( i , j ∈ [ 0 , s ] ) g[x][y]=(x+i,y+j) (i,j\in[0,s]) g[x][y]=(x+i,y+j)(i,j∈[0,s])
- 如果g[x][y]在q中,那么看一下是不是也在qq中,如果是那就继续查找,如果不在qq中,说明不满足小地图的格式。当前(x,y)舍弃,继续下一个q中的点。
- 每次找到一棵树(x+i,y+j)=1既在q也在qq就计数+1。计数超过小地图的1的个数也放弃当前点。
- 当把(x,y)附近的所有子图块都找过了。看看找到的1个数是不是等于小地图的1个数就行了。
AC代码(100分)
#include <iostream>
#include <stdio.h>
#include <unordered_set>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
int n,l,s,b;
int x,y;
struct node{
int xx;
int yy;
node():xx(0),yy(0){}
node(int _x,int _y):xx(_x),yy(_y){}
bool operator==(const node& b)const{
return xx==b.xx&&yy==b.yy;
}
};
struct nodeHash{
size_t operator()(const node& b)const{
return b.xx*10e9+b.yy;
}
};
unordered_set<node,nodeHash>q;
unordered_set<node,nodeHash>qq;
int cnt=0;
int ans=0;
int main(){
scanf("%d%d%d",&n,&l,&s);
rep(i,0,n){
scanf("%d%d",&x,&y);
q.insert({x,y});
}
for(int i=s;i>=0;i--){
rep(j,0,s+1){
scanf("%d",&b);
if(b==1){
cnt++;
qq.insert({i,j});
}
}
}
for(auto u:q){
if(u.xx+s>l||u.yy+s>l)continue;
int temp_ans=0;
int sign=0;
rep(i,0,s+1){
rep(j,0,s+1){
if(q.find({u.xx+i,u.yy+j})!=q.end()){
temp_ans++;
if(qq.find({i,j})==qq.end()){
sign=1;break;
}
if(temp_ans>cnt){
sign=1;
break;
}
}
}
if(sign==1)break;
}
if(temp_ans==cnt&&sign==0)ans++;
}
printf("%d",ans);
return 0;
}
/*
9 20 1
0 0
1 0
5 0
6 1
2 2
7 2
4 3
1 7
2 8
0 1
1 0
*/