题目链接:
http://poj.org/problem?id=1266
题目大意:
给三个点,求出能够覆盖由这三个点组成的圆弧的最小矩形面积。
思路:
根据三个点可以组成一个三角形,那么就能算出这个三角形的外心。然后就能判断出是优弧还是劣弧,进行计算。
注意他的矩形要求是整数,所以要用ceil和floor进行取整。可能会有精度误差,可以考虑ceil时减去eps,floor时加上eps。
代码:
#include
#include
#include
#include
#include
#define PI acos(-1.0)
#define eps 0.00000001
using namespace std;
struct Point{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
};
struct line{
Point a,b;
line(Point a=0,Point b=0):a(a),b(b){}
};
Point p[10005],ch[10005];
line Line[5005];
Point operator + (Point A ,Point B){
return Point(A.x+B.x,A.y+B.y);
}
Point operator - (Point A,Point B){
return Point(A.x-B.x,A.y-B.y);
}
Point operator * (Point A,double p){
return Point(A.x*p,A.y*p);
}
bool operator < (const Point &a,const Point &b){
return a.xP.x)return 1; //left
else if(tmp1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-1;i>=0;i--)
{
while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) m--;
ch[m++]=p[i];
}
if(n) m--;
return m;
}
bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){ //线段规范相交
double c1=Cross(a2-a1,b1-a1);
double c2=Cross(a2-a1,b2-a1);
double c3=Cross(b2-b1,a1-b1);
double c4=Cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
}
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);
}
int main(){
int n;
int T,icase=0;
double ex1,ey1,ex2,ey2,xx,yy;
int S;
double dx,dy;
int mixi,miyi,maxi,mayi;
while(~scanf("%lf%lf%lf%lf%lf%lf",&ex1,&ey1,&ex2,&ey2,&xx,&yy)){
Point O,e1,e2,cc;
e1=Point(ex1,ey1);
e2=Point(ex2,ey2);
cc=Point(xx,yy);
O=circumcenter(e1,e2,cc);
double radius=distances(O,cc);
Point up,down,left,right;
up=Point(O.x,O.y+radius);
down=Point(O.x,O.y-radius);
left=Point(O.x-radius,O.y);
right=Point(O.x+radius,O.y);
// printf("%.0f %.0f %.0f %.0f\n",up.x,up.y,left.x,left.y);
int tt=0;
S=0;
if(SegmentProperIntersection(left,cc,e1,e2))mixi=floor(min(e1.x,e2.x));
else mixi=floor(left.x);
if(SegmentProperIntersection(up,cc,e1,e2))mayi=ceil(max(e1.y,e2.y));
else mayi=ceil(up.y);
if(SegmentProperIntersection(right,cc,e1,e2))maxi=ceil(max(e1.x,e2.x));
else maxi=ceil(right.x);
if(SegmentProperIntersection(down,cc,e1,e2))miyi=floor(min(e1.y,e2.y));
else miyi=floor(down.y);
printf("%d\n",(maxi-mixi)*(mayi-miyi));
}
}
/*
0 1
0 -1
1 0
*/