【计算几何】 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\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的更多相关文章
- Codeforces Beta Round #67 (Div. 2)
Codeforces Beta Round #67 (Div. 2) http://codeforces.com/contest/75 A #include<bits/stdc++.h> ...
- 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 ...
- Codeforces Beta Round #80 (Div. 2 Only)【ABCD】
Codeforces Beta Round #80 (Div. 2 Only) A Blackjack1 题意 一共52张扑克,A代表1或者11,2-10表示自己的数字,其他都表示10 现在你已经有一 ...
- Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】
Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...
- Codeforces Beta Round #79 (Div. 2 Only)
Codeforces Beta Round #79 (Div. 2 Only) http://codeforces.com/contest/102 A #include<bits/stdc++. ...
- Codeforces Beta Round #77 (Div. 2 Only)
Codeforces Beta Round #77 (Div. 2 Only) http://codeforces.com/contest/96 A #include<bits/stdc++.h ...
- Codeforces Beta Round #76 (Div. 2 Only)
Codeforces Beta Round #76 (Div. 2 Only) http://codeforces.com/contest/94 A #include<bits/stdc++.h ...
- Codeforces Beta Round #75 (Div. 2 Only)
Codeforces Beta Round #75 (Div. 2 Only) http://codeforces.com/contest/92 A #include<iostream> ...
- Codeforces Beta Round #74 (Div. 2 Only)
Codeforces Beta Round #74 (Div. 2 Only) http://codeforces.com/contest/90 A #include<iostream> ...
随机推荐
- 十个迅速提升JQuery性能的技巧
本文提供即刻提升你的脚本性能的十个步骤.不用担心,这并不是什么高深的技巧.人人皆可运用!这些技巧包括: 使用最新版本 合并.最小化脚本 用for替代each 用ID替代class选择器 给选择器指定前 ...
- Spring学习-- AOP入门动态代理
AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...
- mybatis的一些特殊符号标识(大于,小于,等于,不等于)
特殊字符 替代符号(红色基本为常用的) & & < < > > ...
- react+redux基础用法
在学react的是,发现一旦我们封装好了我们的组件,那么我们的项目就跟搭积木一样简单快速,可是我们发现了一个问题,在一个页面往往会嵌套很多的组件,子组件必须要通过父组件传递参数才能渲染出数据,我们回想 ...
- python判断操作系统
https://www.crifan.com/python_get_current_system_os_type_and_version_info/ 参考:https://stackoverflow. ...
- HDU3910(数学期望题,题目难懂)
Liang Guo Sha Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 命令行工具PathMarker
一直使用Guake 终端,Guake提供的其中一个功能是快速打开. 大概的意思就是,显示在终端上的数据会经过匹配,如果符合一定的规则,则可以按住ctrl,使用鼠标单击以触发指定操作. 比如对于一个文件 ...
- 在linux下搭建wiki环境【转】
转自:http://blog.csdn.net/chy800/article/details/6906090 由于公司需要一个知识共享的系统,选择wiki来实现.经过准备决定使用Linux+xampp ...
- Ubuntu下查看CPU、内存和硬盘详细信息的几个命令
CPU: 型号:grep "model name" /proc/cpuinfo |awk -F ':' '{print $NF}' 数量:lscpu |grep "CPU ...
- js实现的联想输入
以前也写过一个jQuery的这种插件,但是很多地方根本不用jQuery,这个功能也有很多其它库支持,但是为了用这个功能而加载很多js插件,这样效率明显下降了很多,而且这个东西平时也很常用,所以一决心自 ...