Description:
Darts
https://interunia.unswcpmsoc.com/task/Darts/
Thinking:
This contest is harder than I imaged, this is the second task, and I spent a lot of time but when I checked the Leaderboard and no one has solved it yet, I feel a little bit better.
At first, I thought of simply judging whether this point is in the middle of this circle, using Euclidean distance calculation. But later I found that when there are n circles and m darts, the amount of data is surprisingly large. After the brute force cracking timed out, I had to consider a new method.
We can use the gridded Spatial Indexing
, the specific steps are as follows:
1. Spatial division: Divide the entire plane into grids of equal size (Grid), and map the target and dart to the corresponding grid.
Purpose:
- Reduce the number of targets that need to be calculated.
- For each dart, you only need to check the targets in its grid and adjacent grids.
2. Map Targets to Grids:
- Calculate the bounding box of each target.
- Lower-left corner: ( (x_i - r_i, y_i - r_i) )
- Upper-right corner: ( (x_i + r_i, y_i + r_i) )
- Record all grid cells covered by this rectangle and add the target index to these grid cells.
3. Map Darts to Grids:
For each dart, calculate the grid coordinates where it is located.
4. Check if the Dart Hits a Target:
- For each dart, check all targets in its grid and the adjacent 8 grids.
- Calculate the distance from the dart to the center of each target and determine whether it is less than or equal to the square of the target’s radius, i.e., ( (dx - x_i)^2 + (dy - y_i)^2 \leq r_i^2 ).
Grid Division Parameters
Grid size (GRID_SIZE
):
- Choose an appropriate grid size, such as 500.
- The choice of grid size requires a trade-off between space and time efficiency.
1 | auto get_grid_cell = [&](long long x_n, long long y_n) { |
Coordinate mapping function:
Maps actual coordinates to grid coordinates.
- s is the actual length of each grid cell.
- $min_x$ and $min_y$ are the minimum values among all target and dart coordinates, used to shift the coordinates.
Mapping Targets to Grids
- Iterate over all targets and calculate their covered grid ranges.
- In these grids, record the indices of the targets.
1 | for (int idx = 0; idx < n; ++idx) { |
Mapping Darts to Grids
- For each dart, calculate the grid cell it belongs to.
- No need to store darts in grids; we process them directly.
Checking if Darts Hit Targets
- For each dart, get its grid coordinates ( (gx, gy) ).
- Check the dart’s grid cell and its 8 adjacent grid cells.
- For each target in these grids, calculate the distance to the dart.
- If the distance squared is less than or equal to the target’s radius squared, increment the counter.
1 | for (const auto& p : points) { |
code:
1 | import math |
1 |
|