标签:cross intersect ase ble sed ddl fine The inter
头文件
#include<bits/stdc++.h> #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) using namespace std; typedef long long ll; const int maxn = 1e3+7; const double esp = 1e-6; int dcmp(double x){ if(fabs(x)<esp)return 0; return x<0?-1:1; } struct Point{ double x,y; void read(){scanf("%lf%lf",&x,&y);} Point(double x = 0,double y = 0):x(x),y(y){} }; double Cross(const Point A,const Point B){ return A.x*B.y-A.y*B.x; } double Dot(const Point A,const Point B){ return A.x*B.x+A.y*B.y; } double Len(const Point A){ return sqrt(Dot(A,A)); } double Angle(const Point A,const Point B){ return acos(Dot(A,B)/Len(A)/Len(B)); } Point operator + (const Point A,const Point B){ return Point(A.x+B.x,A.y+B.y); } Point operator - (const Point A,const Point B){ return Point(A.x-B.x,A.y-B.y); } Point operator * (const Point A,const double B){ return Point(A.x*B,A.y*B); } Point operator / (const Point A,const double B){ return Point(A.x/B,A.y/B); } Point Rotate(const Point A,double rad){return Point(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));} //负数表示顺时针 Point Normal(const Point A){return Point(-A.y/Len(A),A.x/Len(A));}//法向量 bool operator == (const Point A,const Point B){return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y); } bool operator != (const Point A,const Point B){return !(A == B);} bool operator < (const Point A,const Point B){return A.x<B.x || (A.x == B.x&&A.y<B.y);} typedef Point Vector; struct Circle{ Point x; double r; void read(){ x.read(); scanf("%lf",&r); } }; bool quickRepel(Point x1,Point y1,Point x2,Point y2){//快速排斥 Point Lx = Point(min(x1.x,y1.x),min(x1.y,y1.y)); Point Rx = Point(max(x1.x,y1.x),max(x1.y,y1.y)); Point Ly = Point(min(x2.x,y2.x),min(x2.y,y2.y)); Point Ry = Point(max(x2.x,y2.x),max(x2.y,y2.y)); Point L = Point(max(Lx.x,Ly.x),max(Lx.y,Ly.y)); Point R = Point(min(Rx.x,Ry.x),min(Rx.y,Ry.y)); return (L.x<=R.x) && (L.y<=R.y); } bool OnSegment(Point P,Point x,Point y){//点在线段上 if(P == x||P == y)return 1; return !dcmp(Cross(x-P,y-P))&&dcmp(Dot(P-x,P-y))<0; } bool straddle(Point x1,Point y1,Point x2,Point y2){//跨立实验(线段是否有交点) if(!quickRepel(x1,y1,x2,y2))return 0; double c1 = Cross(y1-x1,x2-x1),c2 = Cross(y1-x1,y2-x1); double c3 = Cross(y2-x2,x1-x2),c4 = Cross(y2-x2,y1-x2); return dcmp(c1)*dcmp(c2)<=0 && dcmp(c3)*dcmp(c4)<=0; //允许部分重合或在端点重合 //return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0; //必须只有一个交点且不在端点上 } Point LinearIntersection(Point P,Vector v,Point Q,Vector w){//解直线交点 assert(v != w);//Parallel 平行线 Vector u = P-Q; double t = Cross(w,u)/Cross(v,w); return P+v*t; } Point GetLineProjection(Point P,Point A,Point B){//P投影到AB上的点 Vector v = B-A; return A+v*(Dot(v,P-A)/Dot(v,v)); } Point SymmetricPoint(Point P,Point A,Point B){//P关于AB的对称点 return GetLineProjection(P,A,B)*2.0-P; } double DistanceToline(Point P,Point A,Point B){//点到直线距离 Vector v1 = B-A,v2 = P-A; return fabs(Cross(v1,v2))/Len(v1); } double DistanceToSegment(Point P,Point A,Point B){//点到线段距离 if(A == B)return Len(P-A); Vector v1 = B-A,v2 = P-A,v3 = P-B; if(dcmp(Dot(v1,v2))<0)return Len(v2); if(dcmp(Dot(v1,v3))>0)return Len(v3); return fabs(Cross(v1,v2))/Len(v1); }
例题:
Morley‘s Theorem
https://vjudge.net/problem/UVA-11178
注意理解三等分角和三等分边不是一个概念
Point GetPoint(Point A,Point B,Point C){ Vector v1 = C-B; double a1 = Angle(A-B,v1); v1 = Rotate(v1,a1/3); Vector v2 = B-C; double a2 = Angle(A-C,v2); v2 = Rotate(v2,-a2/3); return LinearIntersection(B,v1,C,v2); } int main(){ int T; scanf("%d",&T); while(T--){ Point A,B,C; A.read(),B.read(),C.read(); Point D = GetPoint(A,B,C); Point E = GetPoint(B,C,A); Point F = GetPoint(C,A,B); printf("%.6f %.6f ",D.x,D.y); printf("%.6f %.6f ",E.x,E.y); printf("%.6f %.6f\n",F.x,F.y); } return 0; }
好看的一笔画LA3263
= = 我没找着这个题
狗的距离
https://vjudge.net/problem/UVA-11796
因为没有加速度,所以可以一条狗为参考系,考虑另一条狗的贡献
每次至少跳一个点,所以复杂度也可以保证最多n+m
模拟即可
Point A[maxn],B[maxn]; double Max,Min; void update(Point P,Point A,Point B){ Min = min(Min,DistanceToSegment(P,A,B)); Max = max(Max,Len(P-A)); Max = max(Max,Len(P-B)); } int main(){ int T,n,m,Case = 0; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++)A[i].read(); for(int i=0;i<m;i++)B[i].read(); double LenA = 0,LenB = 0; for(int i=0;i<n-1;i++) LenA += Len(A[i+1]-A[i]); for(int i=0;i<m-1;i++) LenB += Len(B[i+1]-B[i]); int Sa = 0,Sb = 0; Point Pa = A[0],Pb = B[0]; Min = 1e9,Max = -1e9; while(Sa<n-1 && Sb<m-1){ double La = Len(A[Sa+1]-Pa); double Lb = Len(B[Sb+1]-Pb); double T = min(La/LenA,Lb/LenB); Vector Va = (A[Sa+1]-Pa)/La*T*LenA; Vector Vb = (B[Sb+1]-Pb)/Lb*T*LenB; update(Pa,Pb,Pb+Vb-Va); Pa = Pa+Va; Pb = Pb+Vb; if(Pa == A[Sa+1])Sa++; if(Pb == B[Sb+1])Sb++; } printf("Case %d: %.0f\n",++Case,Max-Min); } return 0; }
标签:cross intersect ase ble sed ddl fine The inter
原文地址:https://www.cnblogs.com/revolIA-room/p/11620622.html