I was asked this Interview Question (C++,algos)and had no idea how to solve it.
Given an array say Arr[N] containing Cartesian coordinates of N distinct points count the
It's trivial to see that you can get all the pairs of points and their slope & y-intercepts in O(n^2) time. So the output is:
IndexB Slope Y-Intercept IndexA
Of course, we won't insert any entries where IndexA = IndexB.
Let's have this table indexed on (IndexB,Slope,Y), which forces our insert into this table as O(log(n))
After we fill out this table with new records (B',S',Y',A'), we check to see if we already have an element such that B'=A of the existing table and B!=A' of the new record (meaning we have a unique triplet) that matches the slope and Y-intercept (meaning collinear). If this is the case and A < B < B', increment the count by 1.
EDIT: One clarifying remark. We need to make sure that we fill this table "backwards" first, taking all the pairs that wouldn't satisfy A < B (< C). This ensures that they will exist in the table before we start testing for their existence.
EDIT: Wow my C++ is rusty... took a while.
#include
#include
#include
#include
#include
using namespace std;
#define ADD_POINT(xparam,yparam) { point x; x.x = xparam; x.y = yparam; points.push_back(x); };
#define EPSILON .001
class line {
public:
double slope;
double y;
int a;
int b;
bool operator< (const line &other) const{
if(this->a < other.a)
return true;
else if(this->a==other.a){
if(this->slope-other.slope < -EPSILON)
return true;
else if(fabs(this->slope-other.slope) < EPSILON){
if(this->y-other.y < -EPSILON)
return true;
else
return false;
}else
return false;
}else
return false;
}
line(double slope, double y, int a, int b){
this->slope = slope;
this->y = y;
this->a = a;
this->b = b;
}
line(const line &other){
this->slope = other.slope;
this->y = other.y;
this->a = other.a;
this->b = other.b;
}
};
class point {
public:
double x;
double y;
};
int main(){
vector points;
ADD_POINT(0,0);
ADD_POINT(7,28);
ADD_POINT(1,1);
ADD_POINT(2,3);
ADD_POINT(2,4);
ADD_POINT(3,5);
ADD_POINT(3,14);
ADD_POINT(5,21);
ADD_POINT(9,35);
multiset lines;
for(unsigned int x=0;x::const_iterator p = lines.begin(); p != lines.end(); ++p){
//cout << "Line: " << p->a << " " << p->b << " " << p->slope << " " << p->y << endl;
line theline = *p;
line conj(theline.slope,theline.y,theline.b,-1);
multiset::iterator it;
pair::iterator,multiset::iterator> ret;
ret = lines.equal_range(conj);
for(it = ret.first; it!=ret.second; ++it){
//cout << " Find: " << it->a << " " << it->b << " " << it->slope << " " << it->y << endl;
int a = theline.a;
int b = theline.b;
int c = it->b;
if(a < b && b < c){
cout << a << " " << b << " " << c << std::endl;
}
}
}
//cout << points[0].x << std::endl;
}