题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3902
标程好像是利用后缀数组来优化计算量。
但是由于常数比较大,所以用O(n^2)也可以过掉
方法是把顶点数量扩大一倍,然后枚举对称轴即可
注意到如果i点是对称轴上的点,那么另外一个点必然是i+n
锁起来比较含糊。不过看看代码就明白了。。。我的思路也是抄别个的。。Orz。。
比赛的时候没想到。。T T
#include<stdio.h>
#include<math.h>
#define eps 1e-8
struct point
{
double x;
double y;
};
int n,m;
point pt[20005];
point p[40005];
int Fabs(double x)
{
if(x>eps)
return 1;
else if(x<-eps)
return -1;
else
return 0;
}
double dis(int a,int b)
{
return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
bool SSS(int a,int b,int x,int y)
{
if(Fabs(dis(a,x)-dis(b,x))==0&&Fabs(dis(a,y)-dis(b,y))==0)
return true;
return false;
}
bool check(int a,int b)
{
int i=a,j=a;
while(1)
{
i++;
j--;
if(j==0)
j=m;
if(i==b)
return true;
if(!SSS(i,j,a,b))
return false;
}
}
bool judge()
{
int i;
for(i=1;i<=m/2;i++)
{
if(check(i,i+n))
return true;
}
return false;
}
int main()
{
int i;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%lf%lf",&pt[i].x,&pt[i].y);
pt[n+1]=pt[1];
m=0;
for(i=1;i<=n;i++)
{
m++;
p[m]=pt[i];
m++;
p[m].x=(pt[i].x+pt[i+1].x)/2;
p[m].y=(pt[i].y+pt[i+1].y)/2;
}
p[m+1]=p[1];
if(judge())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}