poj1266Cover an Arc.(三角形的外心)

题目链接:

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
*/


你可能感兴趣的:(POJ)