zoukankan      html  css  js  c++  java
  • 【计算几何】 Codeforces Beta Round #67 (Div. 2) E. Ship's Shortest Path

    读懂题意其实是模板题。就是细节略多。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define EPS 0.00000001
    struct Point
    {
    	double x,y;
    	Point(){}
    	Point(const double &X,const double &Y){x=X;y=Y;}
    	double Length()
    	  {
    	  	return sqrt(x*x+y*y);
    	  }
    }p[3],a[31];
    struct data
    {
    	Point p;
    	int I,J;
    	data(){}
    	data(const Point &P,const int &II,const int &JJ)
    	  {
    	  	p=P;
    	  	I=II;
    	  	J=JJ;
    	  }
    }b[31];
    int e;
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b)
    {
        return Vector(a.x-b.x,a.y-b.y);
    }
    Vector operator + (const Vector &a,const Vector &b)
    {
        return Vector(a.x+b.x,a.y+b.y);
    }
    double Cross(Vector a,Vector b)
    {
        return a.x*b.y-a.y*b.x;
    }
    Vector operator * (const double &K,const Vector &v)
    {
        return Vector(K*v.x,K*v.y);
    }
    Point GetIntersection(Point P,Vector v,Point Q,Vector w)
    {
        return P+(Cross(w,P-Q)/Cross(v,w))*v;
    }
    double dot(Vector a,Vector b)
    {
    	return a.x*b.x+a.y*b.y;
    }
    bool InLine(Point a,Point P,Point Q)
    {
    	if(fabs(Cross(a-P,Q-P))>=EPS)
    	  return 0;
    	return dot(a-P,a-Q)<EPS;
    }
    int n;
    int main()
    {
    //	freopen("s.in","r",stdin);
    	double sum=0;
    	for(int i=0;i<2;++i)
    	  scanf("%lf%lf",&p[i].x,&p[i].y);
    	scanf("%d",&n);
    	for(int i=0;i<n;++i)
    	  scanf("%lf%lf",&a[i].x,&a[i].y);
    	for(int i=0;i<n;++i)
    	  if(fabs(Cross(p[1]-a[(i+1)%n],a[i]-p[0]))<EPS)
    	    {
    	      printf("%.9lf
    ",(p[1]-p[0]).Length());
    	      return 0;
    	    }
    	for(int i=0;i<n;++i)
    	  sum+=(a[(i+1)%n]-a[i]).Length();
    					/*double sum2=0;
    	  	  	  	  	for(int k=i+1;k<j;++k)
    	  	  	  	  	  sum2+=(a[(k+1)%n]-a[k]).Length();
    	  	  	  	  	sum2+=(a[i+1]-tp).Length();
    	  	  	  	  	sum2+=(tp2-a[j]).Length();
    	  	  	  	  	double td=min((tp-p[0]).Length()+(tp2-p[1]).Length(),
    							(tp2-p[0]).Length()+(tp-p[1]).Length());
    	  	  	  	  	printf("%.9lf
    ",td+min(sum-sum2,min(sum2,(tp2-tp).Length()*2.0)));*/
    	for(int i=0;i<n;++i)
    	  {
    	  	Point tp=GetIntersection(p[1],p[1]-p[0],a[i],a[(i+1)%n]-a[i]);
    	  	if(InLine(tp,a[i],a[(i+1)%n]) && InLine(tp,p[0],p[1]))
    	  	  {
    	  	  	for(int j=i+1;j<n;++j)
    	  	  	  {
    	  	  	  	Point tp2=GetIntersection(p[1],p[1]-p[0],a[j],a[(j+1)%n]-a[j]);
    	  	  	  	if(InLine(tp2,a[j],a[(j+1)%n]) && InLine(tp2,p[0],p[1]))
    	  	  	  	  b[++e]=data(tp2,i,j);
    	  	  	  }
    	  	  	for(int j=1;j<=e;++j)
    	  	  	  if(fabs(b[j].p.x-tp.x)>=EPS || fabs(b[j].p.y-tp.y)>=EPS)
    	  	  	    {
    	  	  	      int I=b[j].I,J=b[j].J;
    	  	  	      Point tp2=b[j].p;
    	  	  	      double sum2=0;
    	  	  	  	  for(int k=I+1;k<J;++k)
    	  	  	  	  	sum2+=(a[(k+1)%n]-a[k]).Length();
    	  	  	  	  sum2+=(a[I+1]-tp).Length();
    	  	  	  	  sum2+=(tp2-a[J]).Length();
    	  	  	  	  double td=min((tp-p[0]).Length()+(tp2-p[1]).Length(),
    					(tp2-p[0]).Length()+(tp-p[1]).Length());
    	  	  	  	  printf("%.9lf
    ",td+min(sum-sum2,min(sum2,(tp2-tp).Length()*2.0)));
    	  	  	  	  return 0;
    	  	  	    }
    	  	  		  int I=b[1].I,J=b[1].J;
    	  	  	      Point tp2=b[1].p;
    	  	  	      double sum2=0;
    	  	  	  	  for(int k=I+1;k<J;++k)
    	  	  	  	  	sum2+=(a[(k+1)%n]-a[k]).Length();
    	  	  	  	  sum2+=(a[I+1]-tp).Length();
    	  	  	  	  sum2+=(tp2-a[J]).Length();
    	  	  	  	  double td=min((tp-p[0]).Length()+(tp2-p[1]).Length(),
    					(tp2-p[0]).Length()+(tp-p[1]).Length());
    	  	  	  	  printf("%.9lf
    ",td+min(sum-sum2,min(sum2,(tp2-tp).Length()*2.0)));
    	  	  	  	  return 0;
    	  	  }
    	  }
    	printf("%.9lf
    ",(p[1]-p[0]).Length());
    	return 0;
    }
  • 相关阅读:
    vscode中golang插件配置
    好用的go开源模块汇总
    常用linux指令
    读大嘴生平咨询---->关于商业模式的思考
    photoprism 源码阅读
    C语言的算法
    C语言输出函数和输入函数
    C语言基本概念
    servlet(3)
    servlet(2)
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6358297.html
Copyright © 2011-2022 走看看