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

#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\n",(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\n",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\n",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\n",td+min(sum-sum2,min(sum2,(tp2-tp).Length()*2.0)));
return 0;
}
}
printf("%.9lf\n",(p[1]-p[0]).Length());
return 0;
}

【计算几何】 Codeforces Beta Round #67 (Div. 2) E. Ship's Shortest Path的更多相关文章

  1. Codeforces Beta Round #67 (Div. 2)

    Codeforces Beta Round #67 (Div. 2) http://codeforces.com/contest/75 A #include<bits/stdc++.h> ...

  2. Codeforces Beta Round #67 (Div. 2)C. Modified GCD

    C. Modified GCD time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  3. Codeforces Beta Round #80 (Div. 2 Only)【ABCD】

    Codeforces Beta Round #80 (Div. 2 Only) A Blackjack1 题意 一共52张扑克,A代表1或者11,2-10表示自己的数字,其他都表示10 现在你已经有一 ...

  4. Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】

    Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...

  5. Codeforces Beta Round #79 (Div. 2 Only)

    Codeforces Beta Round #79 (Div. 2 Only) http://codeforces.com/contest/102 A #include<bits/stdc++. ...

  6. Codeforces Beta Round #77 (Div. 2 Only)

    Codeforces Beta Round #77 (Div. 2 Only) http://codeforces.com/contest/96 A #include<bits/stdc++.h ...

  7. Codeforces Beta Round #76 (Div. 2 Only)

    Codeforces Beta Round #76 (Div. 2 Only) http://codeforces.com/contest/94 A #include<bits/stdc++.h ...

  8. Codeforces Beta Round #75 (Div. 2 Only)

    Codeforces Beta Round #75 (Div. 2 Only) http://codeforces.com/contest/92 A #include<iostream> ...

  9. Codeforces Beta Round #74 (Div. 2 Only)

    Codeforces Beta Round #74 (Div. 2 Only) http://codeforces.com/contest/90 A #include<iostream> ...

随机推荐

  1. 关于Maven项目install时出现No compiler is provided in this environment的处理

    关于Maven项目build时出现No compiler is provided in this environment的处理 新配置的Eclipse环境,运行现有项目没问题,一日,从svn上检出了一 ...

  2. Codeforces Round #526 (Div. 2) A.B

    A. The Fair Nut and Elevator 题目链接:https://codeforces.com/contest/1084/problem/A 题意: 一栋房子有n层楼,同时有个电梯( ...

  3. Hbase写入量大导致region过大无法split问题

    最近在线上往hbase导数据,因为hbase写入能力比较强,没有太在意写的问题.让业务方进行历史数据的导入操作,中间发现一个问题,写入速度太快,并且业务数据集中到其中一个region,这个region ...

  4. MySQL 8.0.11(zip)安装及配置

    (1)下载MySQL8.0.11: (2)解压zip文件: 我解压到了D:/MySQL/mysql-8.0.11-winx64 (3)配置环境变量:   右键此电脑->属性 高级系统设置 环境变 ...

  5. sql数据库的链接方式

    今天看见了一个数据库的链接方法,给转载了,记得我刚刚学DAO的时候老是要记载这些东西,所以就上博客园上面看了看,就转过来了... MySQL: String Driver="com.mysq ...

  6. bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp

    这道题 网上题解还是很多很好的 强烈推荐黄学长 码风真的好看 神犇传送门 学习学习 算是道单调队列优化dp的裸题吧 #include<cstdio> #include<cstring ...

  7. jquery hover事件中 fadeIn和fadeOut 效果不能及时停止

    $(".nav ul li").hover(function () { var id = $(this).attr("id"); $(".nav dl ...

  8. Linux ssh的使用

    1.查看SSH客户端版本 有的时候需要确认一下SSH客户端及其相应的版本号.使用ssh -V命令可以得到版本号.需要注意的是,Linux一般自带的是OpenSSH: 下面的例子即表明该系统正在使用Op ...

  9. Linux下的Backlight子系统(二)【转】

    转自:http://blog.csdn.net/weiqing1981127/article/details/8515847 版权所有,转载必须说明转自 http://my.csdn.net/weiq ...

  10. [ Python - 3 ] python3.5中不同的读写模式

    r 只能读.r+可读可写,不会创建不存在的文件.如果直接写文件,则从顶部开始写,覆盖之前此位置的内容,如果先读后写,则会在文件最后追加内容.w+ 可读可写 如果文件存在 则覆盖整个文件不存在则创建w ...