CodeForces - 23D Tetragon【计算几何】

题目链接:https://codeforces.com/contest/23/problem/D

调哭了QAQ

#include <iostream>
#include <cmath>
using namespace std;
typedef double db;
static const db EPS=1e-2;
static const db PI=acos(-1.0);
int sgn(db x)
{
	if(fabs(x)<EPS) return 0;
	if(x<0) return -1;
	return 1;
}
struct Point{
	db x,y;
	Point(){}
	Point(db _x,db _y):x(_x),y(_y){};
	void input() { scanf("%lf%lf",&x,&y); }
	Point operator + (const Point &o)const{ return Point(x+o.x,y+o.y); }
	Point operator - (const Point &o)const{ return Point(x-o.x,y-o.y); }
	db operator ^ (const Point &o)const{ return x*o.y-y*o.x; }
	db operator * (const Point &o)const{ return x*o.x+y*o.y; }
}k,l,m,a,b,c,d;
struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e):s(_s),e(_e){}
	Line(Point p,db angle)
	{
		s=p;
		if(sgn(angle-PI/2)==0) e=(s+Point(0,1));
		else e=(s+Point(1,tan(angle)));
	}
	db angle()
	{
		db k=atan2(e.y-s.y,e.x-s.x);
		if(sgn(k)<0) k+=PI;
		if(sgn(k-PI)==0) k-=PI;
		return k;
	}
	int relation(Point p)
	{
		int c=sgn((p-s)^(e-s));
		if(c<0) return 1;
		else if(c>0) return 2;
		else return 3;
	}
	bool parallel(Line v) { return sgn((e-s)^(v.e-v.s))==0; }
	int linecrossline(Line v)
	{
		if((*this).parallel(v)) return v.relation(s)==3;
		return 2;
	}
	Point crosspoint(Line v)
	{
		db a1=(v.e-v.s)^(s-v.s);
		db a2=(v.e-v.s)^(e-v.s);
		return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
	}
};
int T;
bool check(Point k,Point l,Point m)
{
    Point m1=Point(2*l.x-m.x,2*l.y-m.y);
    Line line1=Line(l,m1),line2=Line(k,l);
    Line line3=Line(Point((l.x+m1.x)/2,(l.y+m1.y)/2),sgn(line1.angle()-PI/2)>=0?line1.angle()-PI/2:line1.angle()+PI/2);
    Line line4=Line(Point((l.x+ k.x)/2,(l.y+ k.y)/2),sgn(line2.angle()-PI/2)>=0?line2.angle()-PI/2:line2.angle()+PI/2);
    if(line3.linecrossline(line4)==2)
    {
        b=line3.crosspoint(line4);
        a=Point(2*k.x-b.x,2*k.y-b.y);
        c=Point(2*l.x-b.x,2*l.y-b.y);
        d=Point(2*m.x-c.x,2*m.y-c.y);
        return sgn((a-b)^(a-c))>0 && sgn((b-c)^(b-d))>0 && sgn((c-d)^(c-a))>0 && sgn((d-a)^(d-b))>0
        || sgn((a-b)^(a-c))<0 && sgn((b-c)^(b-d))<0 && sgn((c-d)^(c-a))<0 && sgn((d-a)^(d-b))<0;
    }
    return false;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		k.input(); l.input(); m.input();
		if(sgn((k-l)^(k-m)) && (check(k,l,m) || check(m,k,l) || check(l,m,k))) printf("YES\n%.10lf %.10lf %.10lf %.10lf %.10lf %.10lf %.10lf %.10lf\n",a.x,a.y,b.x,b.y,c.x,c.y,d.x,d.y);
		else puts("NO\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值