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

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值