計算幾何題


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

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