HDU 4082 Hou Yi's secret 伪相似三角形 && 2011 Asia Beijing Regional Contest

来源:互联网 发布:淘宝天猫入驻 编辑:程序博客网 时间:2024/05/23 12:52

题意是:给你很多点,每三个不共线的点可以连成三角形,相似的三角形可以归为一个集合,问最大的集合三角形的数量。

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;}