您的位置:首页 > 编程语言 > Go语言

注意精度问题 UVA 12300 Smallest Regular Polygon

2014-02-11 18:06 796 查看

Problem A

Smallest Regular Polygon

Given two different points A and B, your task is to find a regular polygon of n sides, passing through these two points, so that the polygon area is minimized.

Input

There will be at most 100 test cases. Each case contains 5 integers xA, yA, xB, yB, n (0<=xA,yA,xB,yB<=100, 3<=n<=10000), the coordinates of A and B, and the number of sides of the regular polygon. The two points A and B are always different. The last test
case is followed by a line with five zeros, which should not be processed.

Output

For each test case, print the smallest area of the regular polygon to six decimal places.

Sample Input

0 0 1 1 4
1 2 3 4 5
2 3 4 5 6
0 0 0 0 0

Output for the Sample Input

1.000000
5.257311
5.196152

Rujia Liu's Present 4: A Contest Dedicated to Geometry and CG Lovers

Special Thanks: Yiming Li

题意:给出两个点,然后要画出一个正n边形经过这两个点,并且面积最小。

思路:。。。很难解释,相当于画出一个正n边形,然后确定那两个点之间的距离为|AB|能让这个n边形面积最小。我的做法是把n边形放在圆中,n为偶数时AB为直径的时候面积最小。如果n为奇数,差不多,不过要求圆的半径。然后一定要化简到不能再化简。。。不然会有精度问题。

代码:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<math.h>
#include<cstring>
#include<algorithm>
using namespace std;
#define eps 1e-10
struct Point
{
Point (double xx=0,double yy=0) : x(xx) , y(yy) { }
double x;
double y;
};

typedef Point Vector;
Vector operator+(Vector v1,Vector v2) { return Vector(v1.x+v2.x,v1.y+v2.y); }
Vector operator-(Vector v1,Vector v2) { return Vector(v1.x-v2.x,v1.y-v2.y); }
Vector operator*(Vector v, double p) { return Vector(v.x*p,v.y*p); }
Vector operator/(Vector v,double p) { return Vector(v.x/p,v.y/p); }

bool operator < (Point a,Point b) { return a.x < b.x || (a.x==b.x && a.y > b.y); }
int dcmp(double x)
{
if (fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
bool operator==(const Point & a,const Point & b)
{
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;
}

double Dot(Vector A,Vector B) { return A.x*B.x+A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A,A)); }
double Angle(Vector A,Vector B) { return acos(Dot(A,B)/Length(A)/Length(B)); }
double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; }
double Area2(Point a,Point b,Point c) { return Cross(b-a,c-a); }
Vector Rotate(Vector A,double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A) { double L = Length(A); return Vector(-A.y/L,A.x/L); }

//点和直线
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
Vector u = P-Q;
double t = Cross(w,u) / Cross(v,w);
return P+v*t;
}
double DistanceToLine(Point P,Point A,Point B)
{
Vector v1 = B-A , v2 = P-A;
return fabs(Cross(v1,v2))/Length(v1);
}
double DistanceToSegment(Point P,Point A,Point B)
{
if (A==B) return Length(P-A);
Vector v1 = B-A , v2 = P-A , v3 = P-B;
if (dcmp(Dot(v1,v2)) < 0) return Length(v2);
else if (dcmp(Dot(v1,v3)) > 0) return Length(v3);
else return fabs(Cross(v1,v2))/Length(v1);
}
Point GetLineProjection(Point P,Point A,Point B)
{
Vector v = B-A;
return A+v*(Dot(v,P-A)/Dot(v,v));
}
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
double c1 = Cross(a2-a1,b1-a1) , c2 = Cross(a2-a1,b2-a1) ,
c3 = Cross(b2-b1,a1-b1) , c4 = Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4)<0;
}
bool OnSegment(Point p,Point a,Point b) {
return dcmp(Cross(a-p,b-p))==0 && dcmp(Dot(a-p,b-p)) < 0;
}
//--------------------------------------------------------------------------------------------
const double PI = 4*atan(1.0);
Point a , b;

int main()
{
int x1 , y1 , x2 , y2 , n;
while (scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&n)==5) {
if (x1+x2+y1+y2+n==0) return 0;
a = Point(x1,y1) , b = Point(x2,y2);
double ang = PI*2/n;
double r = Dot(b-a,b-a)*0.5/(1+cos(ang/2));
double ans;
if (n%2) ans = n*r*sin(ang)*0.5+eps;
else ans = n*sin(ang)*Dot(b-a,b-a)*0.125+eps;
printf("%.6lf\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: