CF 1C Ancient Berland Circus

題目大意:平面上有三個點,屬於一個正多邊形的三個頂點。求該正多邊形的最小面積。多邊形的邊數小於100。

題解:首先比較顯然的是,若一個三角形存在多種正多邊形滿足,邊數最少的正多邊形一定面積最小。因此從小到大枚舉邊數,固定一個頂點,枚舉另外兩個頂點,看三角形是否與給出的三個點構成的三角形相似,若相似則可根據相似比求出整個正多邊形的面積。外接圓的半徑爲r 的正多邊形的面積爲nr22sin(2πn)
在判三角形相似的時候被精度坑了一發…

#include <bits/stdc++.h>

using namespace std;

const double eps = 1e-6;
const double pi = acos(-1.0);

struct node{
    double ang[3];
    bool operator==(const node &a){
        for(int i = 0;i < 3;i++){
            if(fabs(ang[i]-a.ang[i])>eps){
                return false;
            }
        }
        return true;
    }

};

struct Point{
    double x,y;
    Point(double a,double b):x(a),y(b){}
    Point(){}

    Point operator-(const Point &a) const{
        return Point(x-a.x,y-a.y);
    }

    Point operator+(const Point &a) const{
        return Point(x+a.x,y+a.y);
    }

    double operator^(const Point &a)const{
        return x*a.y-y*a.x;
    }

    double length2(){
        return x*x+y*y;
    }
    double length(){
        return sqrt(length2());
    }
};

typedef Point P;


node calc(P a,P b,P c){
    node ret;
    //printf("a x=%f y=%f\n",a.x,a.y);
    //printf("b x=%f y=%f\n",b.x,b.y);
    //printf("c x=%f y=%f\n",c.x,c.y);
    double t1,t2,t3;
    t1 = (a.length2()+b.length2()-c.length2())/(2*a.length()*b.length());
    t2 = (a.length2()+c.length2()-b.length2())/(2*a.length()*c.length());
    t3 = (c.length2()+b.length2()-a.length2())/(2*c.length()*b.length());
   // printf("%f\n%f\n%f\n",t1,t2,t3);
    ret.ang[0] = acos(t1);
    ret.ang[1] = acos(t2);
    ret.ang[2] = acos(t3);
    sort(ret.ang,ret.ang+3);
    return ret;
}

double area(P a,P b){
    return 0.5*fabs(a^b);
}

Point points[150];

int main(){
    P p[3];
    for(int i = 0;i < 3;i++){
        scanf("%lf%lf",&p[i].x,&p[i].y);
    }
    node tri = calc(p[0]-p[1],p[1]-p[2],p[2]-p[0]);
    double are = area(p[0]-p[1],p[1]-p[2]);
    double ans = 0;
    bool flag = false;
    //printf("are=%f\n",are);
    //for(int i = 0;i < 3;i++){
    //    printf("ang%d = %f\n",i,tri.ang[i]);
    //}
    for(int i = 3;i <= 100;i++){
        double totare = 1.0*i*sin(2*pi/i)/2;
        for(int j = 0;j < i;j++){
            double x,y,sita;
            sita = 2*pi/i*j;
            x = 1.0*sin(sita);
            y = 1.0*cos(sita);
            points[j] = Point(x,y);
        }
        for(int j = 1;j < i;j++){
            for(int k = j+1;k < i;k++){
                node tmp = calc(points[0]-points[j],points[j]-points[k],points[k]-points[0]);
                //if(i == 6&&j == 2&&k == 3){
                //    printf("%f %f %f\n",tmp.ang[0],tmp.ang[1],tmp.ang[2]);
                //}
                if(tmp == tri){
                    double ta = area(points[0]-points[j],points[j]-points[k]);
                    ans = are/ta*totare;
                    flag = true;
                    break;
                }
            }
            if(flag) break;
        }
        if(flag) break;
    }
    printf("%.8f\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章