CSES Solution Line Segment Intersection (original) (raw)

Last Updated : 23 Jul, 2025

There are two line segments: the first goes through the points (x 1, y 1 ) and (x 2 ,y 2 ), and the second goes through the points ****(x** 3 ,y 3 ) and (x 4 ,y 4 ).

Your task is to determine if the line segments intersect, i.e., they have at least one common point.

**Example:

**Input: points = {1, 1}, {5, 3}, {1, 2}, {4, 3}
**Output: No

**Input: points = {1, 1}, {5, 3}, {1, 1}, {4, 3}
**Output: No

**Approach:

Steps-by-step approach:

Below are the implementation of the above approach:

C++ `

#include <bits/stdc++.h> using namespace std;

#define int long long #define endl '\n' #define Point complex #define X real() #define Y imag()

// Function to calculate cross product of two vectors AB and AC int crossProduct(Point A, Point B, Point C) { Point AB = B - A; // Vector from A to B Point AC = C - A; // Vector from A to C return (conj(AB) * AC).Y; // Cross product of AB and AC }

// Function to compare two points bool comparePoints(const Point &a, const Point &b) { return (a.X == b.X) ? (a.Y < b.Y) : (a.X < b.X); }

// Function to check if point C lies between point A and B bool isMidPoint(Point A, Point B, Point C) { vector v = {A, B, C}; sort(v.begin(), v.end(), comparePoints); return (v[1] == C); }

// Function to get sign of a number int sign(int x) { return (x > 0) - (x < 0); }

// Function to check if line segments AB and CD intersect bool doIntersect(Point A, Point B, Point C, Point D) { int crossProduct1 = crossProduct(A, B, C); int crossProduct2 = crossProduct(A, B, D); int crossProduct3 = crossProduct(C, D, A); int crossProduct4 = crossProduct(C, D, B); if (crossProduct1 == 0 && isMidPoint(A, B, C)) return true; if (crossProduct2 == 0 && isMidPoint(A, B, D)) return true; if (crossProduct3 == 0 && isMidPoint(C, D, A)) return true; if (crossProduct4 == 0 && isMidPoint(C, D, B)) return true; if (sign(crossProduct1) != sign(crossProduct2) && sign(crossProduct3) != sign(crossProduct4)) return true; return false; }

signed main() { // Hardcoded input vector<vector> points = { {{1, 1}, {5, 3}, {1, 2}, {4, 3}} };

for (auto& point : points) {
    Point A = point[0];
    Point B = point[1];
    Point C = point[2];
    Point D = point[3];
    cout << (doIntersect(A, B, C, D) ? "YES" : "NO") << endl;
}

return 0;

}

Java

/*code by flutterfly / import java.util.;

class Main { // Class to represent complex numbers static class Point { long x, y;

    Point(long x, long y) {
        this.x = x;
        this.y = y;
    }

    Point subtract(Point p) {
        return new Point(this.x - p.x, this.y - p.y);
    }

    long crossProduct(Point p) {
        return this.x * p.y - this.y * p.x;
    }
}

// Function to compare two points
static class PointComparator implements Comparator<Point> {
    public int compare(Point a, Point b) {
        return (a.x == b.x) ? Long.compare(a.y, b.y) : Long.compare(a.x, b.x);
    }
}

// Function to check if point C lies between point A and B
static boolean isMidPoint(Point a, Point b, Point c) {
    List<Point> points = Arrays.asList(a, b, c);
    points.sort(new PointComparator());
    return points.get(1).equals(c);
}

// Function to get sign of a number
static int sign(long x) {
    return Long.compare(x, 0);
}

// Function to check if line segments AB and CD intersect
static boolean doIntersect(Point a, Point b, Point c, Point d) {
    long crossProduct1 = a.subtract(c).crossProduct(b.subtract(c));
    long crossProduct2 = a.subtract(c).crossProduct(d.subtract(c));
    long crossProduct3 = c.subtract(a).crossProduct(b.subtract(a));
    long crossProduct4 = c.subtract(a).crossProduct(d.subtract(a));

    if (crossProduct1 == 0 && isMidPoint(a, b, c))
        return true;
    if (crossProduct2 == 0 && isMidPoint(a, b, d))
        return true;
    if (crossProduct3 == 0 && isMidPoint(c, d, a))
        return true;
    if (crossProduct4 == 0 && isMidPoint(c, d, b))
        return true;
    if (sign(crossProduct1) != sign(crossProduct2) && sign(crossProduct3) != sign(crossProduct4))
        return true;

    return false;
}

public static void main(String[] args) {
    // Hardcoded input
    List<List<Point>> points = new ArrayList<>();
    points.add(Arrays.asList(new Point(1, 1), new Point(5, 3), new Point(1, 2), new Point(4, 3)));

    for (List<Point> point : points) {
        Point A = point.get(0);
        Point B = point.get(1);
        Point C = point.get(2);
        Point D = point.get(3);
        System.out.println(doIntersect(A, B, C, D) ? "YES" : "NO");
    }
}

}

C#

//code by flutterfly using System; using System.Collections.Generic;

class MainClass { // Class to represent complex numbers class Point { public long x, y;

    public Point(long x, long y)
    {
        this.x = x;
        this.y = y;
    }

    public Point Subtract(Point p)
    {
        return new Point(this.x - p.x, this.y - p.y);
    }

    public long CrossProduct(Point p)
    {
        return this.x * p.y - this.y * p.x;
    }
}

// Function to compare two points
class PointComparator : IComparer<Point>
{
    public int Compare(Point a, Point b)
    {
        return (a.x == b.x) ? a.y.CompareTo(b.y) : a.x.CompareTo(b.x);
    }
}

// Function to check if point C lies between point A and B
static bool IsMidPoint(Point a, Point b, Point c)
{
    List<Point> points = new List<Point> { a, b, c };
    points.Sort(new PointComparator());
    return points[1].Equals(c);
}

// Function to get sign of a number
static int Sign(long x)
{
    return x.CompareTo(0);
}

// Function to check if line segments AB and CD intersect
static bool DoIntersect(Point a, Point b, Point c, Point d)
{
    long crossProduct1 = a.Subtract(c).CrossProduct(b.Subtract(c));
    long crossProduct2 = a.Subtract(c).CrossProduct(d.Subtract(c));
    long crossProduct3 = c.Subtract(a).CrossProduct(b.Subtract(a));
    long crossProduct4 = c.Subtract(a).CrossProduct(d.Subtract(a));

    if (crossProduct1 == 0 && IsMidPoint(a, b, c))
        return true;
    if (crossProduct2 == 0 && IsMidPoint(a, b, d))
        return true;
    if (crossProduct3 == 0 && IsMidPoint(c, d, a))
        return true;
    if (crossProduct4 == 0 && IsMidPoint(c, d, b))
        return true;
    if (Sign(crossProduct1) != Sign(crossProduct2) && Sign(crossProduct3) != Sign(crossProduct4))
        return true;

    return false;
}

public static void Main(string[] args)
{
    // Hardcoded input
    List<List<Point>> points = new List<List<Point>>();
    points.Add(new List<Point> { new Point(1, 1), new Point(5, 3), new Point(1, 2), new Point(4, 3) });

    foreach (List<Point> point in points)
    {
        Point A = point[0];
        Point B = point[1];
        Point C = point[2];
        Point D = point[3];
        Console.WriteLine(DoIntersect(A, B, C, D) ? "YES" : "NO");
    }
}

}

JavaScript

// Function to calculate cross product of two vectors AB and AC function crossProduct(A, B, C) { let AB = { X: B.X - A.X, Y: B.Y - A.Y }; // Vector from A to B let AC = { X: C.X - A.X, Y: C.Y - A.Y }; // Vector from A to C return AB.X * AC.Y - AB.Y * AC.X; // Cross product of AB and AC }

// Function to compare two points function comparePoints(a, b) { return (a.X === b.X) ? (a.Y < b.Y) : (a.X < b.X); }

// Function to check if point C lies between point A and B function isMidPoint(A, B, C) { let v = [A, B, C]; v.sort(comparePoints); return (v[1] === C); }

// Function to get sign of a number function sign(x) { return (x > 0) - (x < 0); }

// Function to check if line segments AB and CD intersect function doIntersect(A, B, C, D) { let crossProduct1 = crossProduct(A, B, C); let crossProduct2 = crossProduct(A, B, D); let crossProduct3 = crossProduct(C, D, A); let crossProduct4 = crossProduct(C, D, B); if (crossProduct1 === 0 && isMidPoint(A, B, C)) return true; if (crossProduct2 === 0 && isMidPoint(A, B, D)) return true; if (crossProduct3 === 0 && isMidPoint(C, D, A)) return true; if (crossProduct4 === 0 && isMidPoint(C, D, B)) return true; if (sign(crossProduct1) !== sign(crossProduct2) && sign(crossProduct3) !== sign(crossProduct4)) return true; return false; }

// Hardcoded input let points = [ [{ X: 1, Y: 1 }, { X: 5, Y: 3 }, { X: 1, Y: 2 }, { X: 4, Y: 3 }] ];

for (let point of points) { let A = point[0]; let B = point[1]; let C = point[2]; let D = point[3]; console.log(doIntersect(A, B, C, D) ? "YES" : "NO"); }

Python3

code by flutterfly

import cmath

Function to calculate cross product of two vectors AB and AC

def cross_product(A, B, C): AB = B - A # Vector from A to B AC = C - A # Vector from A to C return AB.conjugate() * AC # Cross product of AB and AC

Function to compare two points

def compare_points(a, b): return (a.real == b.real and a.imag < b.imag) or a.real < b.real

Function to check if point C lies between point A and B

def is_mid_point(A, B, C): v = [A, B, C] v.sort(key=lambda x: (x.real, x.imag)) return v[1] == C

Function to get sign of a number

def sign(x): return (x > 0) - (x < 0)

Function to check if line segments AB and CD intersect

def do_intersect(A, B, C, D): cross_product1 = cross_product(A, B, C) cross_product2 = cross_product(A, B, D) cross_product3 = cross_product(C, D, A) cross_product4 = cross_product(C, D, B) if cross_product1.imag == 0 and is_mid_point(A, B, C): return True if cross_product2.imag == 0 and is_mid_point(A, B, D): return True if cross_product3.imag == 0 and is_mid_point(C, D, A): return True if cross_product4.imag == 0 and is_mid_point(C, D, B): return True if sign(cross_product1.imag) != sign(cross_product2.imag) and sign(cross_product3.imag) != sign(cross_product4.imag): return True return False

Hardcoded input

points = [ [complex(1, 1), complex(5, 3), complex(1, 2), complex(4, 3)] ]

for point in points: A, B, C, D = point print("YES" if do_intersect(A, B, C, D) else "NO")

`

**Time complexity: O(n log n).
**Auxiliary Space: O(1)