给定 N 个相等的圆(可能重叠)和平面上的 M 个点。找到包含最大点数的圆
Given N equal circles (possibly overlapping) and M points on a plane. Find a circle which contains maximum number of points
下图是一个简单的案例。圆圈 1 获胜,因为它包含点数 [1, 2, 5] -- 比任何其他圆圈都多。
根据每个圆圈检查每个点的天真实现给出了时间限制。
他们说“使用哈希”。但是在哪里呢?
#include <iostream>
#include <vector>
using namespace std;
struct Point
{
int x;
int y;
};
int64_t dist(Point p1, Point p2)
{
int64_t dx = p1.x - p2.x;
int64_t dy = p1.y - p2.y;
return dx*dx + dy*dy;
}
int main()
{
int circle_num;
cin >> circle_num;
vector<Point> circles(circle_num);
vector<int64_t> count (circle_num);
for (Point& p : circles)
cin >> p.x >> p.y;
int points_num;
cin >> points_num;
while (points_num--)
{
Point p;
cin >> p.x >> p.y;
for (int i = 0; i != circle_num; ++i)
{
if (dist(p, circles[i]) <= 400)
++count[i];
}
}
int index = 0;
int64_t max_count = 0;
for (int i = 0; i != circle_num; ++i)
{
if (count[i] > max_count)
{
max_count = count[i];
index = i;
}
}
cout << (index + 1) << endl;
}
可能的输入:
3 // number of circles
-1 0 // circle 1 center
1 0 // circle 2 center
2 5 // circle 3 center
3 // number of points
10 0
20 0
22 5
输出:3 -- 圆 3 包含的点数最多
由于圆都是一样大的(800个单位),一个实用的做法是把平面分成一个格子,每个方格401x401个单位,然后用一个hash from (x,y) -> list to收集每个方格中的点。
然后对于每个圆,只需检查它重叠的最多 9 个正方形中的点。
下图是一个简单的案例。圆圈 1 获胜,因为它包含点数 [1, 2, 5] -- 比任何其他圆圈都多。
根据每个圆圈检查每个点的天真实现给出了时间限制。 他们说“使用哈希”。但是在哪里呢?
#include <iostream>
#include <vector>
using namespace std;
struct Point
{
int x;
int y;
};
int64_t dist(Point p1, Point p2)
{
int64_t dx = p1.x - p2.x;
int64_t dy = p1.y - p2.y;
return dx*dx + dy*dy;
}
int main()
{
int circle_num;
cin >> circle_num;
vector<Point> circles(circle_num);
vector<int64_t> count (circle_num);
for (Point& p : circles)
cin >> p.x >> p.y;
int points_num;
cin >> points_num;
while (points_num--)
{
Point p;
cin >> p.x >> p.y;
for (int i = 0; i != circle_num; ++i)
{
if (dist(p, circles[i]) <= 400)
++count[i];
}
}
int index = 0;
int64_t max_count = 0;
for (int i = 0; i != circle_num; ++i)
{
if (count[i] > max_count)
{
max_count = count[i];
index = i;
}
}
cout << (index + 1) << endl;
}
可能的输入:
3 // number of circles
-1 0 // circle 1 center
1 0 // circle 2 center
2 5 // circle 3 center
3 // number of points
10 0
20 0
22 5
输出:3 -- 圆 3 包含的点数最多
由于圆都是一样大的(800个单位),一个实用的做法是把平面分成一个格子,每个方格401x401个单位,然后用一个hash from (x,y) -> list to收集每个方格中的点。
然后对于每个圆,只需检查它重叠的最多 9 个正方形中的点。