UVa 10439 - Temple of Dune

本文介绍了一种计算已知三个顶点坐标时正多边形最小可能边数的方法。通过确定圆心并计算各顶点间的角度,进而枚举验证边数,实现了精确求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出一个正多边形上的三个点的坐标,求至少是正几边形

问题转化:三点可以确定一个圆,由此可求出外接圆的圆心,再根据圆上的三个点求出三个角度,由于题目中说明多边形的边数不会超过200,可直接枚举边数,然后判断即可

注:判断时需要合理控制精度,太小了不够,太大了会出错

#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
const double  pi=acos(-1.0);
typedef struct Vector
{
    double dx;
    double dy;
    double ang;
}Vector;
Vector a[5];
int cmp(Vector a,Vector b)
{
    return a.ang<b.ang;
}
int main()
{
    int n;
    double x1,y1,x2,y2,x3,y3;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);
        //圆心坐标
        double cx=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2*(x3-x1)*(y2-y1)-2*((x2-x1)*(y3-y1)));
        double cy=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2*(y3-y1)*(x2-x1)-2*((y2-y1)*(x3-x1)));
        //连接圆心和三个点的三个向量
        a[0].dx=x1-cx;
        a[0].dy=y1-cy;
        a[1].dx=x2-cx;
        a[1].dy=y2-cy;
        a[2].dx=x3-cx;
        a[2].dy=y3-cy;
        //求夹角
        for(int i=0;i<3;i++)
        {
            a[i].ang=atan2(a[i].dy,a[i].dx);
        }
        sort(a,a+3,cmp);
        double a1,a2,a3;
        a1=a[1].ang-a[0].ang;
        a2=a[2].ang-a[1].ang;
        a3=a[0].ang+2*pi-a[2].ang;
        //printf("%lf %lf %lf\n",a1,a2,a3);
        int ans=-1;
        //枚举过程
        for(int i=3;i<=200;i++)
        {
            double k=2.0*pi/(double)i;
            double b1=a1/k;
            double b2=a2/k;
            double b3=a3/k;
            int s1=fmod(b1,1.0)>=0.5?ceil(b1):floor(b1);
            int s2=fmod(b2,1.0)>=0.5?ceil(b2):floor(b2);
            int s3=fmod(b3,1.0)>=0.5?ceil(b3):floor(b3);
            if(fabs(s1-b1)<1e-5&&fabs(s2-b2)<1e-5&&fabs(s3-b3)<1e-5)
            {
                ans=i;break;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值