cf591d
题意:给出船的最大速度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的更多相关文章
随机推荐
- ubuntu系统虚拟机下共享文件夹
一般情况 1.安装: sudo apt-get install open-vm-dkms 2.挂载: sudo mount -t vmhgfs .host:/ /mnt/hgfs 用以上命令安 ...
- 【转载】<mvc:annotation-driven />注解意义
本文转载自:http://kingliu.iteye.com/blog/1972973 <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式 ...
- 庆祝下,提交了第一个ceph pull request。实现了从0到1的突破
庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...
- 用css3做一个正方体
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- js判断浏览器类型
使用navigator.userAgent和来判断 PC端: <script type="text/javascript">var ua=navigator.userA ...
- consolel API大全-附测试结果
f 简介: JS中默认没有console对象, 这是某些浏览器提供的浏览器内置对象, 低版本IE就没有, 其他主流浏览器应该都有.它能看到结构话的东西,如果是alert,淡出一个对象就是[object ...
- jQuery文件上传插件Uploadify(转)
一款基于flash的文件上传,有进度条和支持大文件上传,且可以多文件上传队列. 这款在flash的基础上增加了html5的支持,所以在移动端也可以使用. 由于官方提供的版本是flash免费,html5 ...
- Linux CentOS6.x ip设置(网卡设置)
修改IP永久生效按以下方法vi /etc/sysconfig/network-scripts/ifcfg-eth0(eth0,第一块网卡,如果是第二块则为eth1)按如下修改ip: DEVICE=et ...
- Linux下使用Hexo搭建github博客
找到一篇靠谱的博客,备份一下: ---------以下原文------------------ Nodejs安装 因为hexo是基于nodejs的应用,所以要先安装nodejs才可以.我这里以Ubun ...
- 在不损坏C盘的情况下为C盘扩容,适用于Win
2016年12月29日14:29:27 参考原文:http://jingyan.baidu.com/article/90808022a6c6b7fd91c80fc8.html 在不损坏磁盘的情况下给某 ...