BestCoder Round #62 (div.2) 1002 Clarke and five-pointed star

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 \le T \le 10)T(1T10),表示数据的组数。
每组数据有55行,每行有两个实数x_i, y_i(-10^9 \le x_i, y_i \le 10^9)xi,yi(109xi,yi109),表示第ii个点的坐标。
输出描述
如果两个量相差小于10^{-4}104,则认为这两个量相等。
对于每组数据,如果这55个点能组成一个五角星,则输出YesYes,否则输出NoNo。(如果55个点相同,那么也能组成一个五角星。)
输入样例
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;
}

       
       
      
      
     
     
    
    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值