題目大意:平面上有三個點,屬於一個正多邊形的三個頂點。求該正多邊形的最小面積。多邊形的邊數小於100。
題解:首先比較顯然的是,若一個三角形存在多種正多邊形滿足,邊數最少的正多邊形一定面積最小。因此從小到大枚舉邊數,固定一個頂點,枚舉另外兩個頂點,看三角形是否與給出的三個點構成的三角形相似,若相似則可根據相似比求出整個正多邊形的面積。外接圓的半徑爲
在判三角形相似的時候被精度坑了一發…
#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;
}