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

#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. mycat 管理MySQL5.7主从搭建

    1.首先安装MySQL ab: 192.168.6.163 master 192.168.6.167 slave master: vi /etc/opt/rh/rh-mysql57/my.cnf.d/ ...

  2. HUSTOJ增加其他语言出现RuntimeError解决办法

    HUSTOJ增加其他语言,如Python.Java.Pascal等等,如果程序是正确的,却报运行错误,添加okcall就行. 具体错误可以看日志: [ERROR] A Not allowed syst ...

  3. fieldset——一个不常用的HTML标签

    fieldset 标签 -- 对表单进行分组 在form表单中,我们可以对form中的信息进行分组归类,如注册表单的form,我们可以将注册信息分组成 基本信息(一般为必填) 详细信息(一般为可选) ...

  4. npm获取配置值的两种方式

    命令行标记 在命令行上放置--foo bar设置foo配置参数为bar. 一个 -- 参数(argument)告诉cli解析器停止读取flags.一个 在命令行结尾的--flag参数(paramete ...

  5. 精通JS正则表达式(转)

    精通JS正则表达式,讲的比较详细,学习正则表达式的朋友可以参考下.    正则表达式可以: •测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡 ...

  6. 复选框 checkbox 选中事件

    项目中用的jquery-1.11 今天需要检测一个checkbox的选中状态,想当然的用 .attr("checked") ,结果发现,无论是否选中,这个值都是 undefined ...

  7. flume高级组件及各种报错

    1,one source two channel 创建conf文件,内容如下: #定义agent名, source.channel.sink的名称 access.sources = r1 access ...

  8. Python学习笔记 使用数据库SQlite Mysql

    SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用当中, 甚至在IOS和Android的APP中都可以集成 Python就内 ...

  9. (七)计算G711语音的打包长度和RTP里timestamp的增长量

    如何计算G711语音等的打包长度和RTP里timestamp的增长量 一般对于不同的语音有不同的打包周期,而不同的打包周期又对应着不同的timestamp in RTP 那么是如何计算的呢,我们通过G ...

  10. Linux编写Shell脚本

    ——<Linux就该这么学>笔记Shell脚本命令的工作方式有两种 交互式: 用户每输入一条命令就立即执行 批处理: 由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中 ...