题目大意:

给你一个角度,让你从一个正n边形中找出一个三个点,使得三个点生成的角度最接近给定角度。本来是想算出以一个点为顶点,另外两个点为一条边的两个端点,的所有角的大小,然后尺取的。后来发现,原来这些角大小一样,对不起数学老师啊。。。。这么麻烦的尺取居然还对了~

代码:

#include<bits/stdc++.h>
using namespace std;
double get_long(double a,double anl,double b)
{
    return sqrt(a*a+b*b-cos(anl)*2*a*b);
}
double get_anl(double a,double b,double c)//c边对应角的大小
{
    return acos((a*a+b*b-c*c)/(2*a*b));
}

int n;
double ask;
double c[100050];
int main()
{
    int temp;
    scanf("%d%d",&n,&temp);

    const double p=atan(1.0)*4;//π
    const double m=(n-2)*p/(double)n;//内角大小
    const double k=100.0;//一边长
    ask=(double)(temp)*p/180.0;
    double t=m;
    double a=100.0;
    double b=get_long(a,t,a);

    c[1]=get_anl(a,b,k);
    t=m-(c[1]);
    for(int i=2;i<n-1;i++)
    {
        a=b;
        b=get_long(a,t,k);
        c[i]=get_anl(a,b,k);
        t=m-(p-t-c[i]);
    }
    int best_a=1,best_b=2;
    double dis=c[1]-ask;
    double best=abs(dis);
    int now_a=1,now_b=2;
    double now=c[1];

    while(1)
    {
        if(now_b>=n-1)break;
        now+=c[now_b];
        now_b++;
        dis=now-ask;
        if(abs(dis)<best)
        {
            best=abs(dis);
            best_a=now_a;best_b=now_b;
        }
        while(now>ask&&now_a!=now_b)
        {
            now-=c[now_a];
            now_a++;
        }
        if(abs(dis)<best)
        {
            best=abs(dis);
            best_a=now_a;best_b=now_b;
        }
    }
    printf("%d %d %d",best_a,n,best_b);
}