hdu 4082

題意:

就是給你n個點,選三個點構成一個三角形,算相似三角形最多的有幾個。

解題思路:

因爲點最多隻有18個所以三個for,因爲判斷三角相似,所以只要將其的邊排序,然後算出三個角,進行比較即可。

注意:

判斷重點,判斷是否共線。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
#include <set>
using namespace std;
#define MAXSZ 20
#define MOD 7001
#define eps 1e-8
int dcmp(double x);
typedef struct node{
    int num,a2,b2,c2;
    double A,B,C,a,b,c;
    node(){
        
    }
    node(int aa,int bb,int cc){
        a2 = aa;
        b2 = bb;
        c2 = cc;
    }
    void getCOSA(){
        A = (c2 + b2 -a2)*1.0/(2*c*b);
    }
    void getCOSB(){
        B = (c2+a2-b2)*1.0/(2*c*a);
    }
    void getCOSC(){
        C = (a2+b2-c2)*1.0/(2*a*b);
    }
    bool sim(int aa,int bb,int cc){
        //return (a==aa)&&(bb==b)&&(c==cc);
        //if(a2*b1==a)
        if((aa*b==bb*a)&&(bb*c==b*cc)&&(aa*c==cc*a))
            return true;
        return false;
    }
    friend bool operator<(node aa,node bb){
        int  tmp = dcmp(aa.A - bb.A);
        if(tmp<0)
            return true;
        if(!tmp){
            tmp = dcmp(aa.B - bb.B);
            if(tmp<0)
                return true;
            if(!tmp){
                tmp = dcmp(aa.C - bb.C);
                return tmp<0;
            }
        }
        return  false;
    }
};
typedef struct point{
    int X,Y;
    point(){
        
    }
    point(int XX,int YY){
        X = XX;
        Y = YY;
    }
    void read(){
        scanf("%d%d",&X,&Y);
    }
    friend point  operator -(point aa,point bb){
        return point(aa.X - bb.X,aa.Y - bb.Y);
    }
    bool operator==(point bb){
        if(X==bb.X&&Y==bb.Y)return true;
        return false;
    }
    void operator=(point bb){
        X = bb.X;
        Y = bb.Y;
    }
};
typedef point Vector;
int n,number;
//vector<node>vt[MOD];
set<node>st;
set<node>::iterator itr;
point po[MAXSZ];
int ans[MOD];
int dcmp(double x){
    if(fabs(x)<eps)return 0;
    return x<0?-1:1;
}
int gcd(int aa,int bb){
    if(!bb)return aa;
    return gcd(bb,aa%bb);
}
int dis2(point aa,point bb){
    point cc = aa - bb;
    return cc.X*cc.X+cc.Y*cc.Y;
}
int cross(Vector aa,Vector bb){
    return aa.X*bb.Y - aa.Y*bb.X;
}
bool isTr(point aa,point bb,point cc){
    Vector dd = aa - bb;
    Vector ee = aa - cc;
    if(cross(dd, ee)==0)return false;
    return true;
}
void swapit(int &a,int &b){
    int tmp;
    if(a>b){
        tmp = a;
        a = b;
        b = tmp;
    }
}
void swap(int &a,int &b,int &c){
    //int tmp;
    swapit(a,b);
    swapit(a,c);
    swapit(b,c);
}
void hashit(int a,int b,int c){
    
    node no;
    no.a2 = a;no.b2 = b;no.c2 = c;
    no.a = sqrt(a*1.0);
    no.b = sqrt(b*1.0);
    no.c = sqrt(c*1.0);
    no.getCOSA();no.getCOSB();no.getCOSC();
    itr = st.find(no);
    int ind;
    if(itr==st.end()){
        no.num = number++;
        ind = no.num;
        st.insert(no);
    }
    else {
        ind = itr->num;
    }
    ++ans[ind];
}
void prepro(){
    int cnt = 0;
    bool vis[20] = {};
    for(int i=0;i<n;++i){
        if(vis[i])continue;
        for(int j=i+1;j<n;++j){
            if(po[i]==po[j]){
                vis[j] = true;
            }
        }
        po[cnt++] = po[i];
    }
    n = cnt;
}
int solve(){
    memset(ans,0,sizeof(ans));
    int maxans = 0;
    int d1,d2,d3,g;
    for(int i=0;i<n;++i){
        for(int j=i+1;j<n;++j){
            for(int k=j+1;k<n;++k){
                if(isTr(po[i],po[j],po[k])){
                    d1 = dis2(po[i],po[j]);
                    d2 = dis2(po[i],po[k]);
                    d3 = dis2(po[j],po[k]);
                    //g = gcd(gcd(d1,d2),d3);
                    //d1/=g;d2/=g;d3/=g;
                    swap(d1,d2,d3);
                    hashit(d1,d2,d3);
                }
            }
        }
    }
    for(int i=0;i<MOD;++i){
        if(maxans<ans[i])
            maxans = ans[i];
    }
    return maxans;
}
void clear(){
    //    for(int i=0;i<MOD;++i){
    //        if(vt[i].size()){
    //            vt[i].clear();
    //        }
    //    }
    if(st.size()){
        st.clear();
    }
}
int main(){
    //    for(int i=17000;;i++){
    //        bool flag = true;
    //        for(int j=2;j<=sqrt(i*1.0);++j){
    //            if(i%j==0){
    //                flag = false;
    //                break;
    //            }
    //        }
    //        if(flag){
    //            printf("%d\n",i);
    //            break;
    //        }
    //    }
    while(scanf("%d",&n)!=EOF){
        if(!n)break;
        number = 0;
        for(int i=0;i<n;++i){
            po[i].read();
        }
        prepro();
        int ans1 = solve();
        printf("%d\n",ans1);
        clear();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章