题目链接:https://vjudge.net/problem/FZU-2035
题意:给出一个图形的n个点,判断是否是轴对称图形
题解:对称轴平分图形,要么垂直平分某条边(或者两条边),其他点关于对称轴对称,要么对称轴经过某个点(或者两个),其他点关于对称轴对称,枚举边和点,点积判断下垂直,找到一个符合的即可
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define eps 1e-8
const int N=510;
struct Point{
int x,y;
}a[N],b[N];
int n,len;
int sgn(double x)
{
if(fabs(x) < eps) return 0;
if(x < 0) return -1;
return 1;
}
int main()
{
int T;
int nn=1;
int l,r;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
len=0;
for(int i=0;i<n;i++)scanf("%d%d",&a[i].x,&a[i].y);
for(int i=0;i<n;i++)
{
l=(i-1+n)%n;
r=(i+1)%n;
if((a[i].x==a[l].x&&a[i].x==a[r].x) || (a[i].y==a[l].y&&a[i].y==a[r].y)) continue;
b[len++]=a[i];
}
int flag=0;
double xx,yy;
int lid,rid;
double x_,y_;
double vx,vy;
double vx_,vy_;
for(int i=0;i<len;i++)
{
xx=(double)(b[i].x+b[(i+1)%len].x)/2;
yy=(double)(b[i].y+b[(i+1)%len].y)/2;
vx=b[(i+1)%len].x-b[i].x;
vy=b[(i+1)%len].y-b[i].y;
int j;
for(j=1;j<(len+1)/2;j++)
{
lid=(i-j+len)%len;
rid=(i+1+j)%len;
x_=(double)(b[lid].x+b[rid].x)/2;
y_=(double)(b[lid].y+b[rid].y)/2;
vx=b[(i+1)%len].x-b[i].x;
vy=b[(i+1)%len].y-b[i].y;
vx_=x_-xx;
vy_=y_-yy;
// cout<<
if(sgn((vx_*vx+vy_*vy))!=0 )
break;
vx=b[lid].x-b[rid].x;
vy=b[lid].y-b[rid].y;
if(sgn((vx_*vx+vy_*vy))!=0 )
break;
}
if(j==(len+1)/2)
{
flag=1;
break;
}
}
for(int i=0;i<len;i++)
{
xx=b[i].x;
yy=b[i].y;
int j;
for(j=1;j<=len/2;j++)
{
lid=(i-j+len)%len;
rid=(i+j)%len;
x_=(double)(b[lid].x+b[rid].x)/2;
y_=(double)(b[lid].y+b[rid].y)/2;
vx_=x_-xx;
vy_=y_-yy;
vx=b[lid].x-b[rid].x;
vy=b[lid].y-b[rid].y;
if(sgn((vx_*vx+vy_*vy))!=0)
break;
}
if(j==len/2+1)
{
flag=1;
}
if(flag) break;
}
printf("Case %d: ",nn++);
printf(flag?"YES\n":"NO\n");
}
return 0;
}
/*
6
6
1 1
1 2
2 2
2 0
0 0
0 1
*/