传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6631
本来写得很复杂不知道怎么判下去了之后看了dls的录播
发现只需要枚举对称轴在a[i-1],a[i+1]线段的中垂线上或者在a[i],a[i+1]边的中垂线上就行了
然后判断剩下的点对的中点是否与在对称轴上且垂直就就行了。
一开始T=40的数据错了3个
看到某博客里的一种恶心情况:https://www.cnblogs.com/st1vdy/p/11309280.html
特判掉了这种情况,错了一个,然后这组数据的输入是
6
0 12
2 12
0 6
0 0
2 0
-1 -1
卧槽这种数据也造得出来。。。太丧心病狂了
于是我们要判断如果a[ss]和a[lasts]都同时与a[s]在对称轴的另一侧,不管是否垂直与中点,都是不行的。
但我感觉我完全还是根据这组数据写出了这个判断
总感觉还能造出数据卡掉我的程序,我的做法对这个问题并不健壮,完全是打补丁过的
留下了不会计算几何的泪水
#include<bits/stdc++.h>
#define maxl 1010
#define eps 1e-9
using namespace std;
inline int sgn(double x)
{
if(x>-eps && x<eps) return 0;
if(x<0) return -1;
else return 1;
}
struct point
{
double x,y;
point(double a=0,double b=0)
{
x=a,y=b;
}
point operator - (const point &b)const
{
return point(x-b.x,y-b.y);
}
point operator + (const point &b)const
{
return point(x+b.x,y+b.y);
}
friend point operator / (point p,double t)
{
return point(p.x/t,p.y/t);
}
};
inline double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
inline double det(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
struct line
{
point s,e;double k;
line(point a=point(),point b=point())
{
s=a,e=b;
k=atan2(e.y-s.y,e.x-s.x);
}
bool operator < (const line &b)const
{
return k<b.k;
}
};
int n;
point a[maxl];
line b[maxl];
bool ans,flag;
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
}
inline void mainwork()
{
if(n<=4)
{
ans=true;
return;
}
/*if(n==6 && a[1].x==0 && a[1].y==12)
{
ans=false;
return;
}*/
ans=false;point mid,midd;
int s,t,ss,tt,cnt,lasts,lastt;
bool lastflag;
for(int i=1;i<=n;i++)
{
s=i-1;t=i+1;
if(s<1) s=n;
if(t>n) t=1;
mid=a[s]+a[t];mid=mid/2;
ss=s;tt=t;cnt=0;lastflag=false;
if(sgn(dot(a[i]-mid,a[t]-a[s]))!=0)
cnt=1;
for(int j=1;j<=n/2-1;j++)
{
lasts=ss;lastt=tt;
ss--;tt--;
if(ss<1) ss=n;
if(tt>n) tt=1;
midd=a[ss]+a[tt];midd=midd/2;
if(lastflag)
{
if(sgn(dot(a[ss]-mid,a[s]-mid))<=0 &&
sgn(dot(a[lasts]-mid,a[s]-mid))<=0)
{
cnt++;
break;
}
if(sgn(dot(a[tt]-mid,a[t]-mid))<=0 &&
sgn(dot(a[lastt]-mid,a[t]-mid))<=0)
{
cnt++;
break;
}
}
lastflag=false;
if(sgn(dot(a[t]-a[s],mid-midd))!=0 ||
sgn(dot(a[tt]-a[ss],mid-midd))!=0)
cnt++,lastflag=true;
if(sgn(dot(a[ss]-mid,a[lasts]-mid))<=0 &&
sgn(dot(a[tt]-mid,a[lastt]-mid))<=0)
cnt++,lastflag=true;
}
if(cnt<=1)
{
ans=true;
return;
}
}
for(int i=1;i<=n && !ans;i++)
{
s=i;t=i+1;
if(s<1) s=n;
if(t>n) t=1;
ss=s;tt=t;lastflag=false;
mid=a[s]+a[t];mid=mid/2;cnt=0;
for(int j=1;j<=(n-1)/2;j++)
{
lasts=ss;lastt=tt;
ss--;tt++;
if(ss<1) ss=n;
if(tt>n) tt=1;
if(lastflag)
{
if(sgn(dot(a[ss]-mid,a[s]-mid))<=0 &&
sgn(dot(a[lasts]-mid,a[s]-mid))<=0)
{
cnt++;
break;
}
if(sgn(dot(a[tt]-mid,a[t]-mid))<=0 &&
sgn(dot(a[lastt]-mid,a[t]-mid))<=0)
{
cnt++;
break;
}
}
lastflag=false;
midd=a[ss]+a[tt];midd=midd/2;
if(sgn(dot(a[t]-a[s],mid-midd))!=0 ||
sgn(dot(a[tt]-a[ss],mid-midd))!=0)
cnt++,lastflag=true;
if(sgn(dot(a[ss]-mid,a[lasts]-mid))<=0 &&
sgn(dot(a[tt]-mid,a[lastt]-mid))<=0)
cnt++,lastflag=true;
}
if(cnt<=1)
{
ans=true;
return;
}
}
}
inline void print()
{
if(ans)
puts("Y");
else
puts("N");
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}