cppAcademy
FROM LEARNING TO COMPETING

Expert.
Put your skills to the test.

Bulgarian Informatics Group A · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group A also includes challenging national-level problems. The 109 National-round tasks shared by Groups A and B retain their existing permanent URLs and explanations. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP A2016 · MediumGeometry

Boxing Game Score

National Olympiad — Regional round (2016 season)

Submission name: game.cpp

Problem summary

For each hit, count across M marked points how many of N disks lie entirely inside the circle centered at that point with the hit radius. Starting with the second hit, double its supplied radius if the preceding hit earned an even number of points. Sum all hit scores.

Input

N M Q; N lines cx cy r; M lines x y; Q strengths.

Output

The final total score.

Constraints

1 ≤ N,Q ≤ 10000; 1 ≤ M ≤ 10; coordinates, radii and strengths are between 1 and 10000. All centers are distinct. Scoring circles are guaranteed not internally tangent to input disks.

Worked example

Official sample; other valid outputs may exist.

Input

4 1 3
2 2 1
3 5 2
6 2 3
8 8 1
4 4
4 3 3

Output

5

Solution analysis

  1. A disk of radius r whose center is distance D from a marked point lies inside a scoring circle of radius s exactly when D+r<s. Precompute this threshold for each of the NM point-disk pairs.
  2. Sort all thresholds together. The score of a hit with effective radius s is the number of thresholds strictly below s, obtained with lower_bound. Remember only the score of the immediately preceding hit to decide doubling.
  3. In the sample radius 4 earns 2. Because this is even, the next strength 3 becomes radius 6 and earns 3. The last hit remains radius 3 and earns zero, for total 5.

Why it works

Each point-disk pair contributes one exactly when its containment threshold is below the effective radius. Sorted threshold counting therefore gives the exact hit score. Induction over hits shows that using the preceding score chooses the correct radius each time, so summing those scores yields the final result.

Complexity: O(NM log(NM)+Q log(NM)) time and O(NM) space.

Watch out. Containment concerns the entire disk, not just its center. The first hit is never doubled; parity refers to the previous hit, not the cumulative total.

Commented C++17 solution

An independently written complete program with standard headers.

// Key idea: Each point-disk pair contributes one exactly when its containment threshold is below the
// effective radius. Sorted threshold counting therefore gives the exact hit score.
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
struct Disk{
    long long x,y,radius;
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m,q;
    cin>>n>>m>>q;
    vector<Disk>disks(n);
    for(Disk&disk:disks){
        cin>>disk.x>>disk.y>>disk.radius;
    }
    vector<long double>thresholds;
    thresholds.reserve(n*m);
    for(int i=0;i<m;++i){
        long long x,y;
        cin>>x>>y;
        for(Disk disk:disks){
            long long dx=x-disk.x,dy=y-disk.y;
            thresholds.push_back(sqrtl(dx*dx+dy*dy)+disk.radius);
        }
    }
    sort(thresholds.begin(),thresholds.end());
    long long total=0,previous=0;
    for(int i=0;i<q;++i){
        int strength;
        cin>>strength;
        int radius=strength;
        if(i>0&&previous%2==0){
            radius*=2;
        }
        previous=lower_bound(thresholds.begin(),thresholds.end(),static_cast<long double>(radius))-
            thresholds.begin();
        total+=previous;
    }
    cout<<total<<'\n';
}

Source: Arena Olimpiici ↗