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

题目链接:

http://poj.org/problem?id=1266

题目大意:

给三个点,求出能够覆盖由这三个点组成的圆弧的最小矩形面积。

思路:

根据三个点可以组成一个三角形,那么就能算出这个三角形的外心。然后就能判断出是优弧还是劣弧,进行计算。

注意他的矩形要求是整数,所以要用ceil和floor进行取整。可能会有精度误差,可以考虑ceil时减去eps,floor时加上eps。

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#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.x<b.x||(a.x==b.x&&a.y<b.y);
}
int dcmp(double x){
	if(fabs(x)<eps)return 0;
	else if(x<0)return -1;
	return 1;
}
bool operator ==(const Point &a,const Point &b){
	return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Point A,Point B){
	return A.x*B.x+A.y*B.y;
}
double Cross(Point A,Point B){
	return A.x*B.y-A.y*B.x;
}
double Length(Point A){
	return sqrt(Dot(A,A));
}
double getdistance(Point P,line A){      //点到直线的距离 
	Point v1=A.b-A.a;
	Point v2=P-A.a;
	return fabs(Cross(v1,v2)/Length(v1));
}
double distances(Point p1,Point p2){  //两点距离 
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
int  LeftofLine(Point P,line A){    //点在线的哪一侧,左侧为负 
	Point c1,c2;
	c1=A.a;
	c2=A.b;
	double tmp=(c1.x-c2.x)/(c1.y-c2.y)*(P.y-c2.y)+c2.x;
	if(tmp>P.x)return 1;         //left
	else if(tmp<P.x)return 2;     //right
	else return 4;
}
bool cmp(Point A ,Point B){
	if(A.x==B.x)return A.y<B.y;
	return A.x<B.x;
}
double Angle(Point A, Point B){        //两向量所成的夹角 
	return acos(Dot(A,B)/Length(A)/Length(B));
}
Point Rotate(Point A,double rad){     //向量逆时针旋转 
	return Point(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Point GetLineIntersection(Point P,Point v,Point Q,Point w){    //两直线交点 
	Point u=P-Q;
	double t=Cross(w,u)/Cross(v,w);
	return P+v*t;
}
int ConvexHull(Point *p,int n,Point *ch){          //凸包 
	sort(p,p+n);
	int m=0;
	for(int i=0;i<n;i++)
	{
		while(m>1&&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
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值