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)T(1 \le T \le 10)T(1≤T≤10),表示数据的组数。 每组数据有555行,每行有两个实数xi,yi(−109≤xi,yi≤109)x_i, y_i(-10^9 \le x_i, y_i \le 10^9)xi,yi(−109≤xi,yi≤109),表示第iii个点的坐标。
输出描述
如果两个量相差小于10−410^{-4}10−4,则认为这两个量相等。 对于每组数据,如果这555个点能组成一个五角星,则输出YesYesYes,否则输出NoNoNo。(如果555个点相同,那么也能组成一个五角星。)
输入样例
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如图
这个题目不用判断凸凹包,刚看到这个题目的时候觉得要判断凸凹包,但是仔细看了图之后,就发现不用判断凸凹包了~。至于证明,这里有点难为小白了~。
这里我的思路很简单:例如样例图1随便找一个点,到其他四个点有四条边,满足两两相同的特点。那能不能满足四条边都长度相同呢?答案是不能,如果都相同的话是组成不了五角星的。所以这里暴力枚举就好了~。
难点在于精度,题目中这样说:
如果两个量相差小于10−410^{-4}10−4,则认为这两个量相等。
所以我们可以忽略掉10^-4以外的数比如:
1.12345678.这里我们就可以忽略掉5678这部分。
然后上代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
float juli(float a,float b,float c,float d)
{
return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
float x[6];
float y[6];
float panduan[6];//用float能更小的损失精度~
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<5;i++)
{
scanf("%f%f",&x[i],&y[i]);
}
int flag=0;
for(int i=0;i<5;i++)//五个点的遍历
{
int cont=0;
for(int j=0;j<5;j++)//每个点对应另外的四个点的边的求值
{
if(i==j)continue;
panduan[cont]=juli(x[i],y[i],x[j],y[j]);//求距离值
cont++;
}
int cishu=0;
for(int k=0;k<cont;k++)
{
for(int l=k+1;l<cont;l++)
{
// printf("%d,%f %f\n",i,panduan[k],panduan[l]);
if(int(panduan[k]*10000)==int(panduan[l]*10000))cishu++;//判断是否相等(这里就用到了上述技巧)
}
}
//printf("%d\n",cishu);
if(cishu<2)flag=1;
}
if(flag==1)
printf("No\n");
else
printf("Yes\n");
}
}

本文详细介绍了如何通过编程快速判断五个点是否能组成一个五角星,包括输入描述、输出描述、代码实现及难点解析。
样例2如图

1252

被折叠的 条评论
为什么被折叠?



