题意:给出船的最大速度v,起点,终点。风在前t秒是一个方向,t秒后就一直是第二个方向。两个方向已知。

船速永远大于风速。问船在自由掌握速度和行驶方向的情况下,最快多久到终点。

分析:首先排除一种方法,那就是让船沿起点和终点的先连线线段行进,用一定的船的分速度抵消风速在行驶垂直方向的分速度。

不能这么做的原因如下,暂时我们把终点方向称作前方,而风与前方垂直的方向称为左或者右。第一个风向可能向左吹,第二个风可能向右吹,这样不需要用船速度去实时抵消风速。

即使开始被吹偏了,后来还是能被吹回来。

真正的做法是二分查找总时间。时间足够长则一定可以到达,不够长则一定不能到达。

不要担心时间太长风会把船吹得太远,因为船速是大于风速的,短时间能到达,长时间更能到达。

对于一个给定的总时间a,我们把船的位移分为三个向量之和,分别是风一和风二和船, 三者的位移。

前两个很好计算,因为方向是固定的。而第三个我们认为它是在从前两个向量之和的位置沿直线向终点前进,这是最佳策略。

我们现在只需要看船能否在a时间内走完两相量和到终点的连线。

这一题的二分查找同样使用了限制循环次数的方式来防止超时。

自由掌握方向的这种运动题,很可能需要拆分速度和位移。

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std; #define d(x) x #define zero(x) (((x)>0?(x):-(x))<eps)
#define eps 1.0E-8
#define MAX_POINT_NUM 0 int double_cmp(double a)
{
if (zero(a))
return ;
return a > ? : -;
} struct Point
{
double x,y;
Point()
{}
Point(double x, double y):x(x), y(y)
{}
Point operator - (Point &a)
{
return Point(x - a.x, y - a.y);
}
bool operator <(const Point &a)const
{
return atan2(y, x) < atan2(a.y, a.x);
}
bool operator == (const Point &a) const
{
return x == a.x && y == a.y;
}
}; double point_dist(Point a)
{
return sqrt(a.x * a.x + a.y * a.y);
} double point_dist(Point a, Point b)
{
return point_dist(a - b);
} double dot_product(Point a, Point b)
{
return a.x * b.x + a.y * b.y;
} double dot_product(Point p0, Point p1, Point p2)
{
return dot_product(p1 - p0, p2 - p0);
} Point s, e;
Point wind1;
Point wind2;
double v, t; void input()
{
int x, y;
scanf("%d%d", &x, &y);
s = Point(x, y);
scanf("%d%d", &x, &y);
e = Point(x, y) - s;
s = Point(, );
scanf("%lf%lf", &v, &t);
scanf("%d%d", &x, &y);
wind1 = Point(x, y);
scanf("%d%d", &x, &y);
wind2 = Point(x, y); } bool ok(double a)
{
double t1 = min(a, t);
double t2 = max(a - t, 0.0);
Point by_wind = Point(t1 * wind1.x + t2 * wind2.x, t1 * wind1.y + t2 * wind2.y);
double dist = point_dist(by_wind - e);
return double_cmp(dist - v * a) <= ;
} double binary_search(double l, double r)
{
for (int i = ; i < ; i++)
{
if (double_cmp(l - r) == )
break;
double mid = (l + r) / ;
if (ok(mid))
{
r = mid;
}else
{
l = mid;
}
}
return l;
} int main()
{
input();
printf("%.18f\n", binary_search(, 1e9));
return ;
}

cf591d的更多相关文章

随机推荐

  1. ECharts学习(3)--toolbox(工具栏)

    1. toolbox:这是ECharts中的工具栏.内置有导出图片.数据视图.动态类型切换.数据区域缩放.重置五个工具. 2. toolbox中的属性,不包含五个工具.里面最主要的就是feature这 ...

  2. SSM整合(三):Spring4与Mybatis3与SpringMVC整合

    源码下载 SSMDemo 上一节整合了Mybatis3与Spring4,接下来整合SpringMVC! 说明:整合SpringMVC必须是在web项目中,所以前期,新建的就是web项目! 本节全部采用 ...

  3. python3使用pyinstaller打包apscheduler出的错

    本来只是想用Python做一个定时任务小工具在服务器上运行,可是服务器在隔离区,各种禁止上外网,使用pip导出列表那种下载库的方法不管用,导致Python的各种库都下不到,官网离线下载又各种缺依赖,好 ...

  4. JAVA面向对象

    JAVA面向对象 对象   我们生活中能看到能摸到的一切事物都是对象.在程序中模拟出生活中的所有东西万物皆对象   只要是对象--属性和行为(方法)   属性   对象有什么   例如:学生有姓名.学 ...

  5. vue组件

    分享出来让思路更成熟. 首先组件是 Vue.js 最强大的功能之一. 可以减少很多的工作量,提高工作效率. 编写一个可复用性的组件,虽然官网上也有.... 编写可复用性的vue组件 具备一下的几个要求 ...

  6. pip 与pip3

    pip 3用于python3 版本 pip2 用于python2版本 pip好像可以通用 "pip2" is for Python2, "pip3″ is for Pyt ...

  7. jq使用技巧

    1. 如何创建嵌套的过滤器 //允许你减少集合中的匹配元素的过滤器,  //只剩下那些与给定的选择器匹配的部分.在这种情况下,  //查询删除了任何没(:not)有(:has)  //包含class为 ...

  8. 使用vlc播放器播放rtsp流视频

    可参考: 使用vlc播放器做rtsp服务器 web网页中使用vlc插件播放相机rtsp流视频 使用vlc进行二次开发做自己的播放器 首先需要安装vlc播放器,下载及安装步骤略 使用vlc播放器播放rt ...

  9. applicationContext.xml

    <bean id="dataSource" parent="parentDataSource"> <property name="u ...

  10. redis 基础知识

    1.安装 sudo apt-get install redis-server 检查Redis服务器程序,执行:ps -aux|grep redis 命令检查Redis服务器状态,执行:netstat ...