Clarke and five-pointed star
Accepts: 237
Submissions: 591
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
克拉克是一名人格分裂患者。某一天克拉克分裂为一个几何学习者,在研究多边形。 在研究某一个多边形的时候,克拉克发现他多次遇到判断5个点是否能组成一个五角星的问题,在这里,这5个点分别代表五角星的五个顶点(顶角上的点)。于是他跑来想你求助,让你写出一个程序快速判定。即对于给出的5个点,判断这5个点是否能组成一个五角星。
输入描述
第一行一个整数T(1≤T≤10),表示数据的组数。 每组数据有5行,每行有两个实数xi,yi(−109≤xi,yi≤109),表示第i个点的坐标。
输出描述
如果两个量相差小于10−4,则认为这两个量相等。 对于每组数据,如果这5个点能组成一个五角星,则输出Yes,否则输出No。(如果5个点相同,那么也能组成一个五角星。)
输入样例
2 3.0000000 0.0000000 0.9270509 2.8531695 0.9270509 -2.8531695 -2.4270509 1.7633557 -2.4270509 -1.7633557 3.0000000 1.0000000 0.9270509 2.8531695 0.9270509 -2.8531695 -2.4270509 1.7633557 -2.4270509 -1.7633557
输出样例
Yes No
Hint
样例1如图样例2如图
容易看出只需要判断这5个点是否在一个正五边形上。
因此我们枚举排列,然后依次判断即可。
判定方法是,五条相邻边相等,五条对角线相等。
#include
#include
#include
#include
using namespace std;
struct ponit
{
double x;
double y;
}a[10];
double get(ponit a, ponit b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
int flag[5];
int main(void)
{
int T;
scanf("%d", &T);
while(T--)
{
int i, j;
for(i = 0; i < 5; i++)
scanf("%lf%lf", &a[i].x, &a[i].y);
memset(flag, 0, sizeof(flag));
int ans = 1;
double x = -1000;
for(i = 0; i < 5; i++)
{
int flag1, flag2;
double MAX1 = 0.0, MAX2 = 0.0;
for(j = 0; j < 5; j++)
{
if(i == j) continue;
if(flag[j] < 2)
{
double tmp = get(a[i], a[j]);
if(MAX1 < tmp)
{
MAX2 = MAX1; flag2 = flag1;
MAX1 = tmp; flag1 = j;
}
else if(MAX2 < tmp)
{
MAX2 = tmp; flag2 = j;
}
}
}
if(MAX1 - MAX2 < 1e-4)
{
double A = get(a[i], a[flag1]);
double B = get(a[i], a[flag2]);
double C = get(a[flag1], a[flag2]);
double tmp = (A*A+B*B-C*C)/(2*A*B);
if(x == -1000)
x = tmp;
else if(x - tmp > 1e-4)
{
ans = 0; break;
}
flag[ flag1 ] ++;
flag[ flag2 ]++;
}
else
{
ans = 0;break;
}
}
if(ans) printf("Yes\n");
else printf("No\n");
}
return 0;
}