CF#1C Ancient Berland Circus(正多边形最小面积)

来源:互联网 发布:手机电脑版淘宝网 编辑:程序博客网 时间:2024/04/27 17:06

题意:给你三个点,叫你求以这三个点为顶点的正多边形的最小面积。

思路:找出以这个三个点为顶点的三角形的外接圆的圆心,则所求的最小面积的正多边形的所有顶点必在这个圆上,然后求这三个点与圆心形成的圆心角,从三个最小的圆心角开始向下枚举角度i,当i是三个圆心角的公约数并且360/i是整数时就跳出,则求出该角度,360/i表示为正几边形,就可以算出最小面积了,这题比较卡精度,枚举以0.000001为单位才过。。。。

#include<iostream>#include<cstdio>#include<string.h>#include<algorithm>#include<math.h>#include<queue>#include<stack>#include<map>#include<vector>#define mm(a,b) memset(a,b,sizeof(a))using namespace std;const int inf=0x7ffffff;const double PI=acos(-1.0);const double eps=1e-2;const double e=2.7182818284590452354;struct point{double x,y;};struct line{point a,b;};double dist(point p1,point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); }point intersection(line u,line v){ point ret=u.a; double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))  /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; }point circumcenter(point a,point b,point c){ line u,v; u.a.x=(a.x+b.x)/2; u.a.y=(a.y+b.y)/2; u.b.x=u.a.x-a.y+b.y; u.b.y=u.a.y+a.x-b.x; v.a.x=(a.x+c.x)/2; v.a.y=(a.y+c.y)/2; v.b.x=v.a.x-a.y+c.y;v.b.y=v.a.y+a.x-c.x; return intersection(u,v); }double getangle(double a,double b,double c){return acos((b*b+c*c-a*a)/(2*b*c));}double angletorad(double angle){return (angle*PI/180);}double radtoangle(double rad){return (rad/PI*180);}int main(){point a,b,c;while(~scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y)){point inter=circumcenter(a,b,c);double r=dist(inter,a);double bc=dist(b,c);double ac=dist(a,c);double ab=dist(a,b);double oc=dist(inter,c);double oa=dist(inter,a);double ob=dist(inter,b);double radA=getangle(ab,oa,ob);double radB=getangle(bc,ob,oc);double radC=getangle(ac,oa,oc);double A=radtoangle(radA);double B=radtoangle(radB);double C=radtoangle(radC);double mina=min(A,min(B,C));double ans;for(double i=mina;i>=0;i-=0.000001){if(fabs((A/i)-(int)(A/i))<=eps && fabs((B/i)-(int)(B/i))<=eps && fabs((C/i)-(int)(C/i))<=eps && fabs((360/i)-(int)(360/i))<=eps){ans=i;break;}}double cnt=(int)(360/ans);double area=0.5*r*r*sin(angletorad(ans))*cnt;printf("%.6lf\n",area);}    return 0;}


原创粉丝点击