CFgym:Glyph Recognition(计算几何)

▶ Given some points in the plane, and 3 ≤ k ≤ 8, find two regular k-gons containing all the points between them.

▶  Each polygon is centered at the origin, i.e. all vertices have equal distance to (0, 0).

▶ Each polygon has a vertex on the positive x-axis.

▶ The inner polygon is the largest such polygon containing none of the sample points.

▶ The outer polygon is the smallest such polygon containing all of the sample points

▶ Over all values of k, maximize the ratio Sinner/Souter of polygon areas.


题意:给一堆点,要求用正3~8边形任意一种,去覆盖这些点,要满足上述条件,令内正多边形面积/外正多边形面积最大。

思路:

要求的是所有点的OC长度,先将点化成极坐标,根据对称,将所有点转移到第一份格子即[0,360/K]内。知道OA的长度和角度,从而根据三角函数轻易求出OB和OC的长度,取长度最小和最大的比一下即可。

# include <bits/stdc++.h>
# define pi acos(-1.0)
using namespace std;
struct node
{
    double dis, ang;
}a[1003];
double cal(int k, int n)
{
    double f = 360.0/k*pi/180.0;
    double imax = 0, imin = 1e18, tmp;
    for(int i=0; i<n; ++i)
    {
        tmp = a[i].ang-(int)(a[i].ang/(360.0/k))*(360.0/k);
        tmp = tmp*pi/180.0;
        double len = cos(tmp-f/2)*(a[i].dis);
        len = len/cos(f/2.0);
        imax = max(imax, len);
        imin = min(imin, len);
    }
    return imin*imin/(imax*imax);
}
int main()
{
    int n, id;
    double x, y, ans = 0;
    scanf("%d",&n);
    for(int i=0; i<n; ++i)
    {
        scanf("%lf%lf",&x,&y);
        a[i].dis = sqrt(x*x+y*y);
        a[i].ang = atan(y/x)*180/pi;
        if(x < 0) a[i].ang += 180;
        if(a[i].ang < 0 && x >= 0) a[i].ang += 360;
    }
    for(int i=3; i<=8; ++i)
    {
        if(cal(i,n) > ans)
        {
            ans = cal(i, n);
            id = i;
        }
    }
    printf("%d %.10f\n",id,ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值