计算几何题


CodeForces1096 C. Polygon for the Angle

题意:

给定一个角度angle
要求输出一个最小的n,满足正n边形中,能够选出三个顶点,这三个顶点连线所构成的角等于angle,如果不存在则输出-1。
保证如果有解,则解不超过998244353
数据范围:1<=angle<180
例如:
54度角,可由10边形构成
在这里插入图片描述

思路:

在这里插入图片描述
图中黄色的三个角角度是相同的,证明:
先画出外接圆,则这三个角都是圆周角,存在定理:圆周角度数等于其圆弧对应圆心角度数的一半
而多边形为正多边形,因此这三个角的圆弧是等长的,因此这三个角的圆心角度数相同,那么圆周角度数也相同

显然黄色的角是这个多边形中所能构造的的最小角,
能够发现:只要是最小角的倍数,且不超过多边形最大角(即内角),那么这个多边形都可以构造出来
正n边形内角公式:180(n-2)/n
最小角计算:先计算最小角对应的圆心角,然后除以2进行了,容易推导出圆心角=180-内角,
也可以这样推:发现n-2个最小角可以组成内角,所以最小角=内角/(n-2),结合内角公式会发现最小角=180/n

先打表试试最大的n是多少,然后判断一下能否暴力。
打表发现n=360的时候就能够把1到179的角度全部表示出来。
因此预把n=3到n=360所能构造出的所有角打表出来然后对于每个询问O(1)输出即可

code:

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-6;
map<int,int>mark;
signed main(){
    for(int i=3;;i++){
        double mi=180.0/i;//记得用180.0而不是180
        for(int j=1;j<=i-2;j++){
            double t=mi*j;
            int tt=(int)t;
            if(t-tt<=eps&&!mark[tt]){
                mark[tt]=i;
            }
        }
        if(mark.size()==179){
            break;
        }
    }
    int T;
    cin>>T;
    while(T--){
        int angle;
        cin>>angle;
        cout<<mark[angle]<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章