题意是:给你很多点,每三个不共线的点可以连成三角形,相似的三角形可以归为一个集合,问最大的集合三角形的数量。
Trick:有三点共线以及重合的点,所以需要点去重和判定三点共线
解法:水暴力,去重后枚举每三个点,如果不共线就把三条边排序,除以最大公约数,放入结构体,再加一重for循环 判定这个三角形是否存在。O(n^4) = 15ms 数据太水了!!
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
const int maxn=500000;
const double eps=1e-8;
const double pi = acos(-1.0);
inline int dcmp(const double& x) {return (x>eps)-(x<-eps);}
struct Point
{
int x, y;
Point(int x=0, int y=0): x(x),y(y) {}
Point operator-(const Point& p) const {return Point(x-p.x,y-p.y);}
bool operator<(const Point& p) const {if(x!=p.x) return x<p.x; return y<p.y;}
bool operator==(const Point& p) const {return x==p.x&&y==p.y;}
bool read(){scanf("%d%d",&x,&y);return true;}
};
inline int gcd(int a, int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
inline int dist(const Point& a,const Point& b) {return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);}
inline int Cross (const Point& a, const Point& b) {return a.x*b.y-a.y*b.x;}
Point p[maxn];
struct node
{
int a, b, c, d;
node(int a=0, int b=0, int c=0, int d=0):a(a),b(b),c(c),d(d) {}
bool operator==(const node& n) {return a==n.a&&b==n.b&&c==n.c&&d==n.d ;}
};
pair<node,int> v[maxn];
int tnum = 0;
int main()
{
//freopen("in.txt","r",stdin);
int n;
while(~scanf("%d", &n) && n)
{
for(int i = 0 ; i < n ; ++ i)
{
p[i].read();
}
sort(p,p+n);
n = unique(p,p+n)-p;
tnum = 0;
for(int i = 0 ; i < n ; ++ i)
{
for(int j = i + 1; j < n ; ++ j)
{
for(int k = j + 1; k < n ; ++ k)
{
if(Cross(p[i]-p[j], p[i]-p[k])==0) continue;
int d1 = dist(p[i],p[j]), d2 = dist(p[j],p[k]), d3 = dist(p[i],p[k]);
if(d1>d2) swap(d1, d2); if(d1>d3) swap(d1, d3); if(d2>d3) swap(d2, d3);
int d4 = d1; int temp;
temp = gcd(d1, d2); d1/=temp;d2/=temp;
temp = gcd(d3, d4); d3/=temp;d4/=temp;
node tmp = node(d1,d2,d3,d4);
bool flag = false;
for(int i = 0 ; i < tnum ; ++i )
{
if(v[i].first==tmp)
{
v[i].second ++;
flag = true;
break;
}
}
if(!flag)
{
v[tnum].first = tmp;
v[tnum++].second = 1;
}
}
}
}
int ans = 0;
for(int i = 0 ; i < tnum ; ++ i)
{
ans = max(ans, v[i].second);
}
printf("%d\n",ans);
}
return 0;
}