传送门:点击打开链接
题意:判断一个点是否为三角形四心(重心、垂心、内心、外心)的任意一个。
分析:写这篇博客主要是为了复习几何模板。重心是三条中线的交点坐标为((x1+x2+x3)/3,(y1+y2+y3)/3);垂心是三条高线的交点,坐标利用线段垂直的性质(向量的内积为0)解一个方程组;内心是内接圆的圆心,也是利用线段垂直的性质(向量内积为0)解一个方程组;外心是外接圆的圆心,利用到三个点顶点距离相同的性质解一个方程组即可。其实这题没必要求出四心坐标,带进去判断就行了。出题人本来想卡double精度的,但是失败了,本来是只能使用long long的。标程会在后面给出。另外(设向量a(x1,y1)向量b(x2,y2) a∥b表示a=λb,即x1*y2-x2*y1=0 a⊥b表示a*b=0,即x1x2+y1y2=0)。
我的代码:
#include<bits/stdc++.h> using namespace std; #define eps 1e-7 struct p{ double x,y; }; ///外心 p out(p a,p b,p c){ p s; double a1=2*(b.x-a.x),b1=2*(b.y-a.y),a2=2*(c.x-a.x),b2=2*(c.y-a.y); double c1=b.x*b.x-a.x*a.x+b.y*b.y-a.y*a.y,c2=c.x*c.x-a.x*a.x+c.y*c.y-a.y*a.y; s.x=(b1*c2-b2*c1)/(a2*b1-a1*b2); s.y=(a2*c1-a1*c2)/(a2*b1-a1*b2); return s; } ///内心 p in(p a,p b,p c){ p s; double aa=sqrt((c.y-b.y)*(c.y-b.y)+(c.x-b.x)*(c.x-b.x)); double bb=sqrt((c.y-a.y)*(c.y-a.y)+(c.x-a.x)*(c.x-a.x)); double cc=sqrt((b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x)); s.x=(aa*a.x+bb*b.x+cc*c.x)/(aa+bb+cc); s.y=(aa*a.y+bb*b.y+cc*c.y)/(aa+bb+cc); return s; } ///重心 p zhong(p a, p b,p c){ p s; s.x=(a.x+b.x+c.x)/3,s.y=(a.y+b.y+c.y)/3; return s; } ///垂心 p chui(p a,p b,p c){ p s; double a1=c.x-b.x,b1=c.y-b.y,a2=b.x-a.x,b2=b.y-a.y; double c1=a.x*(c.x-b.x)+a.y*(c.y-b.y); double c2=c.x*(b.x-a.x)+c.y*(b.y-a.y); s.x=(b1*c2-b2*c1)/(a2*b1-a1*b2); s.y=(a2*c1-a1*c2)/(a2*b1-a1*b2); return s; } bool ck(p a,p b){ if(fabs(a.x-b.x)<eps && fabs(a.y-b.y)<eps ) return true; return false; } int main(){ p a,b,c,d; while(cin>>a.x>>a.y>>b.x>>b.y>>c.x>>c.y>>d.x>>d.y) if( ck(d,zhong(a,b,c)) || ck(d,chui(a,b,c)) || ck(d,out(a,b,c)) || ck(d,in(a,b,c)) ) cout<<"Yes"<<endl; else cout<<"No"<<endl; }
标程:
#include <bits/stdc++.h> using namespace std; #define zeros(a,n) memset(a,0,(n)*sizeof(a[0])) typedef long long LL; typedef unsigned long long ULL; const LL modn = 1e9+7; struct point { LL x, y; point operator +(const point &rhs) const { return (point){x + rhs.x, y + rhs.y}; } point operator -(const point &rhs) const { return (point){x - rhs.x, y - rhs.y}; } point operator *(const LL &rhs) const { return (point){x * rhs, y * rhs}; } LL operator *(const point &rhs) const { return x * rhs.x + y * rhs.y; } bool operator==(const point &rhs) const { return x == rhs.x && y == rhs.y; } }; LL quickpow(LL a, LL n, LL p) { LL ans = 1; while(n) { if(n & 1) ans = ans * a % p; a = a * a % p; n >>= 1; } return ans; } LL sqr(LL x) { return x * x; } LL xmult(const point &lhs, const point &rhs) { return lhs.x * rhs.y - rhs.x * lhs.y; } bool isorthocenter(point a, point b, point c, point o) { return (b-a)*(c-o)==0 && (c-b)*(a-o)==0 && (a-c)*(b-o)==0; } bool isbarycenter(point a, point b, point c, point o) { return a + b + c == o*3; } bool isexcenter(point a, point b, point c, point o) { LL la = (o-a)*(o-a); LL lb = (o-b)*(o-b); LL lc = (o-c)*(o-c); return la == lb && lb == lc; } bool isincenter(point a, point b, point c, point o) { LL ta = xmult(b-a, o-a); LL tb = xmult(c-b, o-b); LL tc = xmult(a-c, o-c); if(ta < 0 || tb < 0 || tc < 0) return false; LL la = sqr(ta%modn) % modn * quickpow((b-a)*(b-a)%modn, modn-2, modn) % modn; LL lb = sqr(tb%modn) % modn * quickpow((c-b)*(c-b)%modn, modn-2, modn) % modn; LL lc = sqr(tc%modn) % modn * quickpow((a-c)*(a-c)%modn, modn-2, modn) % modn; return la == lb && lb == lc; } int main() { point a, b, c, o; scanf("%lld %lld", &a.x, &a.y); scanf("%lld %lld", &b.x, &b.y); scanf("%lld %lld", &c.x, &c.y); scanf("%lld %lld", &o.x, &o.y); if(xmult(b-a, c-a) < 0) swap(b, c); bool flag = false; flag |= isorthocenter(a, b, c, o); flag |= isbarycenter(a, b, c, o); flag |= isexcenter(a, b, c, o); flag |= isincenter(a, b, c, o); if(flag) puts("Yes"); else puts("No"); return 0; }