题目链接
题目描述
求解思路
- 哈希集合:由于
L
的数据范围较大,我们通过矩阵存储整个地图并不现实。因此,可以将每个点的信息存放在一个哈希集合中,根据藏宝图上的点去判断能否和集合里边的点对应上。 - 解题思路:
- 创建一个
Point
类来存放点的数据,因为需要用到哈希集合,所以重写equals
方法和hashCode
方法。 map
数组存放藏宝图的坐标。在进行遍历时,依次假设每个点作为藏宝图的起点,将起点对应上之后更新藏宝图与大地图对应点的坐标,flag
表示当前点作为藏宝图起点是否成立。(map[j][k] == 1) != set.contains(new Point(mapX + j, mapY + k))
:表示藏宝图中的点和集合中的点没有对应上。mapX + k > L || mapY + j > L
:表示藏宝图上的点已经越界。
- 创建一个
- 需要注意:
- 因为需要用到哈希集合,
Point
类在进行比较时比较的是属性值x
和y
,所以需要重写equals
方法和hashCode
方法。详情可见:为什么重写 equals 方法就必须重写 hashCode 方法? - 在更新藏宝图的坐标时,需要注意区分横纵坐标。确保横坐标对应横坐标,纵坐标对应纵坐标。
- 因为需要用到哈希集合,
实现代码
import java.util.HashSet;
import java.util.Objects;
import java.util.Scanner;
class Point {
long x;
long y;
public Point(long x, long y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj == null || getClass() != obj.getClass()) {
return false;
} else {
Point point = (Point) obj;
return x == point.x && y == point.y;
}
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long L = in.nextLong();
int S = in.nextInt();
HashSet<Point> set = new HashSet<>();
Point[] points = new Point[n];
for (int i = 0; i < n; i ++) {
long x = in.nextLong();
long y = in.nextLong();
points[i] = new Point(x, y);
set.add(points[i]);
}
int[][] map = new int[S + 1][S + 1];
for (int i = S; i >= 0; i --) {
for (int j = 0; j <= S; j ++) {
map[i][j] = in.nextInt();
}
}
int ans = 0;
// 依次假设每个点作为藏宝图的起点
for (int i = 0; i < n; i++) {
// 将起点对应上之后更新藏宝图与大地图对应点的坐标
long mapX = points[i].x;
long mapY = points[i].y;
boolean flag = true;
for (int j = 0; j <= S; j ++) {
for (int k = 0; k <= S; k ++) {
// 如果点没有对应上或者出现越界
if ((map[j][k] == 1) != set.contains(new Point(mapX + j, mapY + k))
|| mapX + j > L || mapY + k > L) {
flag = false;
break;
}
}
if (!flag) {
break;
}
}
if (flag) {
ans ++;
}
}
System.out.println(ans);
}
}