struct Slope
{
int dy,dx;
int sign;
};
struct Line {
Point p1,p2;
Slope slp;
int power;
int begin_point_power;
bool vis;
};
struct cmp_line
{
bool operator()(const Line& l1, const Line& l2)
{
if(l1.p1.x == l2.p1.x)
{
return l1.p1.y < l2.p1.y;
}
return l1.p1.x < l2.p1.x;
}
};
struct cmp_point
{
bool operator()(const Point& p1, const Point& p2)
{
if(p1.x == p2.x) return p1.y < p2.y;
return p1.x < p2.x;
}
};
struct cmp_slope
{
bool operator()(const Slope& p1, const Slope& p2)
{
if(p1.sign != p2.sign)
{
return p1.sign < p2.sign;
}
else
{
long long int left = p1.dy * p2.dx;
long long int right = p2.dy * p1.dx;
if(p1.sign == 1)
{
return left < right;
}
else
{
return right > left;
}
}
return 0;
}
};
class Solution {
public:
int gcd(int x, int y)
{
if(y == 0) return x;
return gcd(y, x % y);
}
Slope get_slope(int dy, int dx)
{
Slope slp;
(dy < 0 && dx > 0) || (dy > 0 && dx < 0) ? slp.sign = -1 : slp.sign = 1;
if(dy < 0) dy = -dy;
if(dx < 0) dx = -dx;
int g = gcd(dy, dx);
dy /= g;
dx /= g;
slp.dy = dy;
slp.dx = dx;
return slp;
}
int maxPoints(vector<Point>& points)
{
int size = points.size();
if(size == 1) return 1;
map<Point, int, cmp_point> M1;
map<Point, int, cmp_point>::iterator mit1;
for(int i = 0; i < size; i++)
{
Point p = points[i];
mit1 = M1.find(p);
if(mit1 != M1.end())
{
int second = (*mit1).second;
M1.erase(mit1);
M1.insert(make_pair(p, second + 1));
}
else
{
M1.insert(make_pair(p, 1));
}
}
vector<Point> lst;
vector<Point>::iterator vit1;
vector<int> cnt;
printf("points:\n");
for(mit1 = M1.begin(); mit1 != M1.end(); mit1++)
{
lst.push_back((*mit1).first);
cnt.push_back((*mit1).second);
}
size = lst.size();
map<int, int> M2;
map<int, int>::iterator mit2;
for(int i = 0; i < size; i++)
{
mit2 = M2.find(lst[i].x);
if(mit2 != M2.end())
{
int second = (*mit2).second;
M2.erase(mit2);
M2.insert(make_pair(lst[i].x, second + cnt[i]));
}
else
{
M2.insert(make_pair(lst[i].x, cnt[i]));
}
}
int ans1 = 0;
for(mit2 = M2.begin(); mit2 != M2.end(); mit2++)
{
ans1 = max(ans1, (*mit2).second);
}
vector<Line> lines;
for(int i = 0; i < size; i++)
{
for(int j = i + 1; j < size; j++)
{
Point p1 = lst[i], p2 = lst[j];
if(p1.x == p2.x)
{
continue;
}
Slope slp = get_slope(p2.y - p1.y, p2.x - p1.x);
Line line = {p1, p2, slp, cnt[i] + cnt[j], cnt[i], false};
lines.push_back(line);
}
}
sort(lines.begin(), lines.end(), cmp_line());
for(int i = 0; i < (int)lines.size();i++)
{
printf("(%d,%d) -> (%d,%d), slope = %d / %d sign = %d, power = %d\n",
lines[i].p1.x,lines[i].p1.y,
lines[i].p2.x,lines[i].p2.y,
lines[i].slp.dy,lines[i].slp.dx,lines[i].slp.sign,
lines[i].power);
}
int ans2 = 0;
map<Slope, int, cmp_slope> M3;
map<Slope, int, cmp_slope>::iterator mit3;
if(lines.size() > 0)
{
Line line = lines[0];
for(int i = 0; i < (int)lines.size(); i++)
{
if(lines[i].p1.x != line.p1.x || lines[i].p1.y != line.p1.y)
{
for(mit3 = M3.begin(); mit3 != M3.end(); mit3++)
{
ans2 = max(ans2, (*mit3).second);
}
M3.clear();
M3.insert(make_pair(lines[i].slp, lines[i].power));
line = lines[i];
}
else
{
Slope slp = lines[i].slp;
mit3 = M3.find(slp);
if(mit3 != M3.end())
{
int second = (*mit3).second;
M3.erase(mit3);
M3.insert(make_pair(slp, second + lines[i].power - lines[i].begin_point_power));
}
else
{
M3.insert(make_pair(slp, lines[i].power));
}
}
}
for(mit3 = M3.begin(); mit3 != M3.end(); mit3++)
{
ans2 = max(ans2, (*mit3).second);
}
}
printf("ans1 = %d ans2 = %d\n",ans1, ans2);
return max(ans1, ans2);
}
};