-1

Finding the number of intersections of n line segments with endpoints on two parallel lines.

Let there be two sets of n points:

A={p1,p2,…,pn} on y=0 B={q1,q2,…,qn} on y=1 Each point pi is connected to its corresponding point qi to form a line segment.

point

I need to write a code using divide-and-conquer algorithm which returns the number of intersection points of all n line segments.

for example:

input:

3
1 101
-234 234
567 765 

output:

1

I coded as below but it I have wrong answers.

can anyone help me with this code or give me another solution for the question?

#include<iostream>
#include <vector>
#include<algorithm>

using namespace std;

    void merge1(vector< pair <int, int> > vect, int l, int m, int r)
    {
        int n1 = m - l + 1;
        int n2 = r - m;

        vector< pair <int, int> > vect_c_l(n1);
        vector< pair <int, int> > vect_c_r(n2);

        for (int i = 0; i < n1; i++)
            vect_c_l[i] = vect[l + i];
        for (int j = 0; j < n2; j++)
            vect_c_r[j] = vect[m + 1 + j];

        int i = 0;
        int j = 0;

        int k = l;
        
        while (i < n1 && j < n2) {
            if (vect_c_l[i].first <= vect_c_r[j].first) {
                vect[k] = vect_c_l[i];
                i++;
            }
            else {
                vect[k] = vect_c_r[j];
                j++;
            }
            k++;
        }

    
        while (i < n1) {
            vect[k] = vect_c_l[i];
            i++;
            k++;
        }

        while (j < n2) {
            vect[k] = vect_c_r[j];
            j++;
            k++;
        }
    }

    int merge2(vector< pair <int, int> > vect, int l, int m, int r)
    {
        int n1 = m - l + 1;
        int n2 = r - m;
        int inv_count = 0;
        vector< pair <int, int> > vect_c_l(n1);
        vector< pair <int, int> > vect_c_r(n2);

        for (int i = 0; i < n1; i++)
            vect_c_l[i] = vect[l + i];
        for (int j = 0; j < n2; j++)
            vect_c_r[j] = vect[m + 1 + j];

    
        int i = 0;
        int j = 0;

        int k = l;

        while (i < n1 && j < n2) {
            if (vect_c_l[i].second < vect_c_r[j].second) {
                vect[k] = vect_c_l[i];
                i++;
            }
            else {
                vect[k] = vect_c_r[j];
                j++;
                inv_count = inv_count + (m - i);

            }
            k++;
        }


        while (i < n1) {
            vect[k] = vect_c_l[i];
            i++;
            k++;
        }

        while (j < n2) {
            vect[k] = vect_c_r[j];
            j++;
            k++;
        }
        return inv_count;
    }

    void mergeSort1(vector< pair <int, int> > vect, int l, int r) {
        if (l >= r) {
            return;
        }
        int m = l + (r - l) / 2;
        mergeSort1(vect, l, m);
        mergeSort1(vect, m + 1, r);
        merge1(vect, l, m, r);
    }

    int mergeSort2(vector< pair <int, int> > vect, int l, int r) {
        int  inv_count = 0;
        if (r > l) {
            int m = l + (r - l) / 2;

            inv_count += mergeSort2(vect, l, m);
            inv_count += mergeSort2(vect, m+ 1, r);

            /*Merge the two parts*/
            inv_count += merge2(vect, l, m + 1, r);
        }
        return inv_count;
    
    }

int main() {
    int n,c=0;
    
    cin >> n;
    int a, b;
    vector< pair <int, int> > vect;

    for (int i = 0;i < n;i++) {
        cin >> a >> b;
        vect.push_back(make_pair(a, b));
    }
    mergeSort1(vect,0,n-1);

    cout << mergeSort2(vect,0, n - 1);
}

Lily
  • 142
  • 9

2 Answers2

0

I'd take advantage of the idea that computing whether the segments intersect is much simpler than computing where they intersect. Two segments intersect if their x values are on different sides of one another on y=1 and y=0. (i.e. if both x values on one segment are both smaller than the others, or both larger).

Objects make this easy to state. Build a segment object who's main job is to determine whether it intersects another instance.

class Segment {
  constructor(x) {
    this.x0 = x[0];
    this.x1 = x[1];
  }
  // answer whether the reciever intersects the passed segment
  intersects(segment) {
    // this is ambiguous in the problem, but assume touching endpoints
    // count as intersections
    if (this.x0 === segment.x0 || this.x1 === segment.x1) return true;
    let sort0 = this.x0 < segment.x0
    let sort1 = this.x1 < segment.x1
    return sort0 !== sort1
  }
}

let input = [
  [1, 101],
  [-234, 234],
  [567, 765]
];
let segments = input.map(x => new Segment(x))

// check segments with one another in pairs
let pairs = segments.map((v, i) => segments.slice(i + 1).map(w => [v, w])).flat();
let intersections = pairs.reduce((acc, p) => p[0].intersects(p[1]) ? acc + 1 : acc, 0)
console.log(intersections)
danh
  • 62,181
  • 10
  • 95
  • 136
-1

You can also see the problem by abstracting from all the lines.

If there were no intersection that would mean that the order of indexes on both parallel lines are the same.

So the number of intersections are equal to the number of swaps you need to perform on neughbor -points to get the same order of indexes on both sides

In your example you have the two sequences of indexes
1,3,4,2 on the upper line
2,1,4,3 on the lower line

to convert the lower sequence by swapping neighbours, you need 4 swaps:

    2,1,4,3   start
->  1,2,4,3
->  1,4,2,3
->  1,4,3,2
->  1,3,4,2  = upper sequence
MrSmith42
  • 9,961
  • 6
  • 38
  • 49