題意:
就是給你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;
}