对于每条对称轴,某个点有两种情况:要不然在对称轴上,要不然在对称轴一侧。不妨依此进行分类讨论。
考虑
1
号点,如果它不在对称轴上直接枚举它的对称点。如果它在对称轴上,考虑
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
const double eps=1e-8;
const int maxn=1010,p=131,mod=1000007;
int cmp(double x)
{
if (x>eps) return 1;
if (fabs(x)<=eps) return 0;
return -1;
}
struct Vector
{
double x,y;
void rd()
{
scanf("%lf%lf",&x,&y);
}
bool operator < (const Vector &v) const
{
int c=cmp(x-v.x);
if (c==0) return cmp(y-v.y)==-1;
return c==-1;
}
Vector operator + (const Vector &v) const
{
return (Vector){x+v.x,y+v.y};
}
Vector operator - (const Vector &v) const
{
return (Vector){x-v.x,y-v.y};
}
Vector operator * (const double &k) const
{
return (Vector){x*k,y*k};
}
Vector operator / (const double &k) const
{
return (Vector){x/k,y/k};
}
}a[maxn];
typedef Vector Point;
double dot(Vector v,Vector u)
{
return v.x*u.x+v.y*u.y;
}
double cross(Vector v,Vector u)
{
return v.x*u.y-v.y*u.x;
}
double len(Vector v)
{
return sqrt(dot(v,v));
}
Point midpoint(Point p,Point q)
{
return (p+q)/2;
}
Vector normal(Vector v)
{
return (Vector){-v.y,v.x};
}
struct Line
{
Point p;
Vector v;
};
bool online(Point p,Line l)
{
return cmp(cross(p-l.p,l.v))==0;
}
double dis(Point p,Line l)
{
return fabs(cross(p-l.p,l.v))/len(l.v);
}
Line perbi(Point p,Point q)
{
return (Line){midpoint(p,q),normal(p-q)};
}
Point symm(Point p,Line l)
{
Vector v=normal(l.v);
v=v/len(v);
v=v*(2*dis(p,l));
Point q1=p+v,q2=p-v;
if (cmp(dot(q1-p,l.p-p))==1) return q1;
return q2;
}
set<Vector> s;
int n;
int check(Line l)
{
for (int i=1;i<=n;i++)
if (!s.count(symm(a[i],l))) return 0;
return 1;
}
int main()
{
//freopen("b.in","r",stdin);
Line l;
int ans=0;
scanf("%d",&n);
for (int i=1;i<=n;i++) a[i].rd(),s.insert(a[i]);
for (int i=2;i<=n;i++)
if (check(perbi(a[1],a[i]))) ans++;
if (check((Line){a[1],a[2]-a[1]})) ans++;
for (int i=3;i<=n;i++)
{
l=perbi(a[2],a[i]);
if (online(a[1],l)&&check(l)) ans++;
}
printf("%d\n",ans);
}