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的更多相关文章
随机推荐
- DDNS动态更新
/// <summary> /// DnsPod DDNS工具类 /// </summary> public class DDNSToolkit { private stati ...
- 开发socketserver 以及定制开发自己的FTP服务器
socket server 示例 #服务端程序 import socketserver class TcpHandler(socketserver.BaseRequestHandler): def h ...
- Android疑难杂症收集
在渲染前获取 View 的宽高 5种手势工具类 软键盘用法总结 Android中Shape的使用 Android只能动态注册的广播Action Android 悬浮窗权限各机型各系统适配大全 录音权限 ...
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'dd' in 'where clause'
今天在使用mysql数据库查找数据的时候报错,错误信息如下: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown co ...
- [转]Pythoin中的Lambda表达式
引用自:http://www.cnblogs.com/evening/archive/2012/03/29/2423554.html 在学习python的过程中,lambda的语法时常会使人感到困惑, ...
- C#计算一段程序运行时间的三种方法
第一种方法利用System.DateTime.Now: static void SubTest() { DateTime beforDT = System.DateTime.Now; //耗时巨大的代 ...
- pureftp在centos下与MySQL搭配使用
概述 pure-ftpd是linux下的一个ftp服务端,据说安全性较高.我在centos6下用yum安装pure-ftpd,并配置了通过MySQL进行用户的增删改查,以及对应到apache的web目 ...
- div+css:div中图片垂直居中
div中图片垂直居中 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...
- Android源码——Activity组件的启动过程
根Activity启动过程 Launcher启动MainActivity的过程主要分为6个步骤: 一.Launcher向ActivityManagerService发送一个启动MainActivity ...
- Theano Graph Structure
Graph Structure Graph Definition theano's symbolic mathematical computation, which is composed of: A ...