▶ 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;
}