#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<iostream> #include<string> #include<set> #include<map> #include<vector> #include<queue> #include<bitset> #include<algorithm> #include<time.h> using namespace std; void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);} #define MS(x,y) memset(x,y,sizeof(x)) #define MC(x,y) memcpy(x,y,sizeof(x)) #define MP(x,y) make_pair(x,y) #define ls o<<1 #define rs o<<1|1 typedef long long LL; typedef unsigned long long UL; typedef unsigned int UI; template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;} template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;} const int N=10,M=0,Z=1e9+7,ms63=1061109567; int casenum,casei; struct point { double x,y; }a[N],p0,p1,p2; double b[N]; int s[N]; bool choose_point(point p1,point p2) { if(p1.x!=p2.x)return p1.x<p2.x; else return p1.y<p2.y; } double cp(point p0,point p1,point p2) { double x1=p1.x-p0.x; double y1=p1.y-p0.y; double x2=p2.x-p0.x; double y2=p2.y-p0.y; double tmp=x1*y2-x2*y1; return tmp; } bool angle_sort(point p1,point p2) { double cp_=cp(p0,p1,p2); if(cp_==0)return p1.y<p2.y; return cp_>0; } double LEN(point p) { return sqrt(p.x*p.x+p.y*p.y); } double DIS(point a,point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } double dcmp(double x,double y) { if(fabs(x-y)<1e-4)return 0; return x<y?-1:1; } bool check() { sort(a+1,a+6,choose_point);p0=a[1]; sort(a+2,a+6,angle_sort); //这一步必不可少,否则可以被hack掉>_< int num=0; for(int i=1;i<=5;i++) { if(dcmp(a[i].x,a[i+1].x))continue; if(dcmp(a[i].y,a[i+1].y))continue; ++num; } if(num==5)return 1; if(num)return 0; int top=0;s[++top]=1;s[++top]=2; for(int i=3;i<=5;i++) { p0=a[s[top-1]]; p1=a[s[top]]; p2=a[i]; if(cp(p0,p1,p2)<0)return 0; else s[++top]=i; } s[++top]=1;s[++top]=2; //方法一:判定是否5条边长度相同,5条对角线长度相同 double dis; dis=DIS(a[5],a[1]); for(int i=1;i<5;i++)if(dcmp(DIS(a[i],a[i+1]),dis))return 0; dis=DIS(a[1],a[3]); if(dcmp(DIS(a[1],a[4]),dis))return 0; if(dcmp(DIS(a[2],a[4]),dis))return 0; if(dcmp(DIS(a[2],a[5]),dis))return 0; if(dcmp(DIS(a[3],a[5]),dis))return 0; return 1; /*方法二:判断5条边的长度是否相同 double dis=DIS(a[s[5]],a[s[6]]); for(int i=1;i<5;i++) { double tmp=DIS(a[s[i]],a[s[i+1]]); if(dcmp(tmp,dis)return 0; } return 1;*/ /*方法三:判断5个角的大小是否相同 for(int i=1;i<=5;i++) { p1=a[s[i]]; p0=a[s[i+1]]; p2=a[s[i+2]]; p1.x-=p0.x;p1.y-=p0.y; p2.x-=p0.x;p2.y-=p0.y; double top=p1.x*p2.x+p1.y*p2.y; double bot=LEN(p1)*LEN(p2); b[i]=acos(top/bot); } for(int i=1;i<5;i++)if(dcmp(b[i],b[i+1]))return 0; return 1;*/ } int main() { scanf("%d",&casenum); for(casei=1;casei<=casenum;casei++) { for(int i=1;i<=5;i++)scanf("%lf%lf",&a[i].x,&a[i].y); puts(check()?"Yes":"No"); } return 0; } /* 【trick&&吐槽】 1,我是傻叉,把向量看成了量,导致不理解如何判精度误差。 2,我是傻叉,cosθ=(a·b)/(|a||b|)的变量对应都写错了,以至于到最后都没有AC第一题,真是蠢炸了。 3,我是傻叉,这场涉及到精度,说是只要两个量相差1e-4,那么这两个量就是相等的。 于是一组(0 0 0 0 0 0 0 0 0 0.0001)的数据应该输出为Yes,可以hack一半的人+1500分。 然而一来我没有成功做出这题,二来进而导致了采取胡乱hack。 其实hack是可以看给定数据对应的输出的。这样我就会发现很多人上面数据输出No 于是这场比赛就可以分数大涨,然后走向人生巅峰,赢取白富美…… 唉,结果都泡汤了。我真是个傻叉。 4,ps:atan2排序还是不稳,如果有点坐标在(0,0),排序会出问题 【题意】 给你二维平面上的5个点,让你判断这5个点是否可以恰好组成正五边形。 【类型】 平面几何 【分析】 方法1:五条相邻边相等,五条对角线相等。 方法2:求凸包,五条边长度相同 方法3:求凸包,五个角度大小相同 我是傻叉,我用的方法是方法3,写起来最难,精度误差最大。然后还让我写错变量,于是就GG啦! 【数据】 0 0 0 0 0 0 0 0 0 0.0001 input 3.0000000 0.0000000 0.9270509 2.8531695 0.9270509 -2.8531695 -2.4270509 1.7633557 -2.4270509 -1.7633557 output Yes input -2.4270509 -1.7633557 3.0000000 0.0000000 0.9270509 2.8531695 0.9270509 -2.8531695 -2.4270509 1.7633557 output Yes */