我就不说官方题解有多坑了
V图那么高端的玩意儿
被精度坑粗翔了
AC前
AC后
简直不敢相信
只能怪自己没注意题目For the distance d1 and d2, if fabs(d1-d2)<1e-7, we think d1 == d2
有空再补充V图的做法吧。。本人也是第一次接触V图
//大白p263 #include <cmath> #include <cstdio> #include <cstring> #include <set> #include <iostream> #include <vector> #include <algorithm> using namespace std; const double eps=1e-8;//精度 const int INF=1<<29; const double PI=acos(-1.0); int dcmp(double x){//判断double等于0或。。。 if(fabs(x)<eps)return 0;else return x<0?-1:1; } struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y){} }; typedef Point Vector; typedef vector<Point> Polygon; Vector operator+(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}//向量+向量=向量 Vector operator-(Point a,Point b){return Vector(a.x-b.x,a.y-b.y);}//点-点=向量 Vector operator*(Vector a,double p){return Vector(a.x*p,a.y*p);}//向量*实数=向量 Vector operator/(Vector a,double p){return Vector(a.x/p,a.y/p);}//向量/实数=向量 bool operator<( const Point& A,const Point& B ){return dcmp(A.x-B.x)<0||(dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)<0);} bool operator==(const Point&a,const Point&b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;} bool operator!=(const Point&a,const Point&b){return a==b;} struct Segment{ Point a,b; Segment(){} Segment(Point _a,Point _b){a=_a,b=_b;} bool friend operator<(const Segment& p,const Segment& q){return p.a<q.a||(p.a==q.a&&p.b<q.b);} bool friend operator==(const Segment& p,const Segment& q){return (p.a==q.a&&p.b==q.b)||(p.a==q.b&&p.b==q.a);} }; struct Circle{ Point c; double r; Circle(){} Circle(Point _c, double _r):c(_c),r(_r) {} Point point(double a)const{return Point(c.x+cos(a)*r,c.y+sin(a)*r);} bool friend operator<(const Circle& a,const Circle& b){return a.r<b.r;} }; struct Line{ Point p; Vector v; double ang; Line() {} Line(const Point &_p, const Vector &_v):p(_p),v(_v){ang = atan2(v.y, v.x);} bool operator<(const Line &L)const{return ang < L.ang;} }; double Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//|a|*|b|*cosθ 点积 double Length(Vector a){return sqrt(Dot(a,a));}//|a| 向量长度 double Angle(Vector a,Vector b){return acos(Dot(a,b)/Length(a)/Length(b));}//向量夹角θ double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//叉积 向量围成的平行四边形的面积 double Area2(Point a,Point b,Point c){return Cross(b-a,c-a);}//同上 参数为三个点 double DegreeToRadius(double deg){return deg/180*PI;} double GetRerotateAngle(Vector a,Vector b){//向量a顺时针旋转theta度得到向量b的方向 double tempa=Angle(a,Vector(1,0)); if(a.y<0) tempa=2*PI-tempa; double tempb=Angle(b,Vector(1,0)); if(b.y<0) tempb=2*PI-tempb; if((tempa-tempb)>0) return tempa-tempb; else return tempa-tempb+2*PI; } double torad(double deg){return deg/180*PI;}//角度化为弧度 Vector Rotate(Vector a,double rad){//向量逆时针旋转rad弧度 return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); } Vector Normal(Vector a){//计算单位法线 double L=Length(a); return Vector(-a.y/L,a.x/L); } Point GetLineProjection(Point p,Point a,Point b){//点在直线上的投影 Vector v=b-a; return a+v*(Dot(v,p-a)/Dot(v,v)); } Point GetLineIntersection(Point p,Vector v,Point q,Vector w){//求直线交点 有唯一交点时可用 Vector u=p-q; double t=Cross(w,u)/Cross(v,w); return p+v*t; } double DistanceToSegment(Point p,Segment s){//点到线段的距离 if(s.a==s.b) return Length(p-s.a); Vector v1=s.b-s.a,v2=p-s.a,v3=p-s.b; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1); } bool isPointOnSegment(Point p,Segment s){//点在线段上 return dcmp(DistanceToSegment(p,s))==0; } //-------------------------------------- //-------------------------------------- //-------------------------------------- //-------------------------------------- //-------------------------------------- Point city[55],bases[55]; int ans[55][55]; int sfrom[55]; Vector norm[55][55]; int n,m; bool judge(Point p,int k){ double dis=Length(p-bases[k]); for(int i=1;i<=m;i++)if(i!=k&&dcmp(dis-Length(p-bases[i])-eps)>0) return false; return true; } int main() { while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%lf%lf",&city[i].x,&city[i].y); for(int i=1;i<=m;i++) scanf("%lf%lf",&bases[i].x,&bases[i].y); for(int i=1;i<=m;i++){ for(int j=i+1;j<=m;j++){ norm[i][j]=Normal(bases[i]-bases[j]); } } memset(ans,-1,sizeof ans); int k,star,en; scanf("%d",&k); for(int i=1;i<=n;i++){ double temp=INF; int mins=-1; for(int j=1;j<=m;j++){ if(dcmp(temp-Length(bases[j]-city[i]))>0){ temp=Length(bases[j]-city[i]); mins=j; } } sfrom[i]=mins; } while(k--){ scanf("%d%d",&star,&en); if(ans[star][en]==-1){ ans[en][star]=ans[star][en]=0; Line train(city[star],city[en]-city[star]); for(int i=1;i<=m;i++){ for(int j=i+1;j<=m;j++){ Vector pingfenxian=norm[i][j]; Point midp; midp.x=(bases[i].x+bases[j].x)/2; midp.y=(bases[i].y+bases[j].y)/2; if(dcmp(Cross(train.v,pingfenxian))==0) continue; Point jiaodian=GetLineIntersection(train.p,train.v,midp,pingfenxian); if(isPointOnSegment(jiaodian,Segment(city[star],city[en]))>0){ ans[star][en]+=judge(jiaodian,i); } } } } printf("%d ",ans[star][en]); ans[en][star]=ans[star][en]; } } return 0; }