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 A2017 · MediumGeometry

Distinct Segment Slopes

National Olympiad — Municipal round (2017 season)

Submission name: slope.cpp

Problem summary

Count the distinct inclinations of nondegenerate segments. Inclination is measured from the left endpoint, or upward for a vertical segment, so reversing endpoints does not change the slope.

Input

n, followed by endpoint coordinates x1 y1 x2 y2.

Output

The number of distinct slopes.

Constraints

0 < n < 100; coordinates are positive integers less than 100; endpoints differ.

Worked example

Official sample; other valid outputs may exist.

Input

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

Output

3

Solution analysis

  1. Represent a segment by its integer direction (dx,dy). Flip signs if dx<0, or if dx=0 and dy<0, to choose the left-to-right or upward direction.
  2. Divide both components by gcd(|dx|,|dy|), producing one canonical primitive vector per slope. Insert those vectors into a set and output its size.
  3. The sample has normalized directions (3,1), (0,1), and (1,−1). Parallel segments share a direction regardless of their lengths.

Why it works

Two segments have equal inclination exactly when their oriented direction vectors are positive scalar multiples. Dividing by the greatest common divisor gives identical primitive integer vectors exactly in this case. The set therefore has one element for every distinct inclination.

Complexity: O(n log n) time and O(n) space.

Watch out. Do not use floating-point angles. All vertical segments have the same positive inclination.

Commented C++17 solution

An independently written complete program with standard headers.

// Key idea: Two segments have equal inclination exactly when their oriented direction vectors are
// positive scalar multiples. Dividing by the greatest common divisor gives identical primitive integer
// vectors exactly in this case.
#include<iostream>
#include<set>
#include<utility>
#include<numeric>
#include<cstdlib>
using namespace std;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    set<pair<int,int>>slopes;
    for(int i=0;i<n;++i){
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        int dx=x2-x1,dy=y2-y1;
        if(dx<0||(dx==0&&dy<0)){
            dx=-dx;
            dy=-dy;
        }
        int divisor=gcd(abs(dx),abs(dy));
        slopes.insert({dx/divisor,dy/divisor});
    }
    cout<<slopes.size()<<'\n';
}

Source: Arena Olimpiici ↗