题意:给出一个轮子,上面有一个随着它转动的传感器在圆周上,给出一个指定距离m,和轮子向前行进的速度v以及轮子的半径r。问让传感器通过该距离最少需要多少时间。

分析:首先我们列出传感器行进距离与时间的轮子行进距离的关系:f(c) = c+r*sin(c/r)。其中c是距离,r是半径。该公式表示传感器从轮子正上方开始运行索性进的距离。

我们可以先去除一种情况,就是距离m是直径2r的整数倍,那么传感器在开始点和结束点所处的角度是相同的,无论从哪个角度开始所需的时间都是一样的。

我们只考虑非整数倍的情况。

要看传感器行进速度的变化,我们需要对这个函数f关于c进行求导。

求得导数是:f'(c) = 1+cos(c/r)。这就是传感器速度的函数。而这个函数图像与x轴所夹的面积就是行进距离。

那么,我们现在的任务就变成了在这个图像上截取一段,使得与x轴所夹的面积是m,且要保证我们截取的横向长度最短。(因为速度是一定的,距离和时间成正比)

假设我们截取了x=a到x=b。那么一定有f'(a)=f'(b)。如果两者不等,例如f'(a)<f'(b),我只要将右边缘向右平移一点点,保证面积不变的话,就需要将左边缘向右平移更多。

因为我们如果把这个增量看成小长方体,如果左右平移量相等,f'(a)<f'(b)导致右边进来的就比左边进来的长方体高,那面积就变了。

既然f'(a)=f'(b),就一定a在图像的递增区域,b在递减区域,否则还会出现上面的情况,或者就是m是2r的整数倍。

也就是说两边缘必须对称,也就是说选区的中间是最高点或者最低点。我们只需要对两种情况分别进行二分查找即可。

二分查找的时候查找轮子的行进长度,每次观察f(c)>=m/2是否成立。

二分查找有个需要特别注意的地方。如果每次只是限定L和R的差值是不行的。差值设大了就会出现WA,设小了会TLE。

需要限定二分迭代的次数为50次左右。不知道是不是其他的比赛或者OJ也有这种情况。

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std; #define d(x) #define zero(x) (((x)>0?(x):-(x))<eps)
#define eps 1.0E-8 int double_cmp(double a)
{
if (zero(a))
return ;
return a > ? : -;
} int n, radius, v;
int dist; bool top_ok(double bike_dist)
{
double ret = bike_dist + radius * sin(bike_dist / radius);
return double_cmp(ret * 2.0 - dist) >= ;
} bool bottom_ok(double bike_dist)
{
double ret = bike_dist - radius * sin(bike_dist / radius);
return double_cmp(ret * 2.0 - dist) >= ;
} double binary_search(bool (*ok)(double))
{
double l = max(0.0, dist / 2.0 - * radius);
double r = dist / 2.0 + * radius;
int cnt = ;
while (double_cmp(r - l) > )
{
double mid = (l + r) / ;
if (ok(mid))
r = mid;
else
l = mid;
cnt++;
if (cnt > )
break;
}
d(printf("%.2f\n", l / radius / / 3.14));
return l;
} double work()
{
double time_top = binary_search(&top_ok) / v;
double time_bottom = binary_search(&bottom_ok) / v;
d(printf("%.2f %.2f\n", time_top, time_bottom));
return min(time_top, time_bottom) * ;
} int main()
{
scanf("%d", &n);
scanf("%d%d", &radius, &v);
for (int i = ; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
dist = b - a;
printf("%.12f\n", work());
}
return ;
}

cf595d的更多相关文章

随机推荐

  1. django authenticate

    程序少不了验证用户与权限分配.通过 Django 自带以及我们一些扩展就能够满足验证与权限的需求. 我在使用 Django 遇到的"login(request, user) 之后,再重定向这 ...

  2. C#软件设计——小话设计模式原则之:单一职责原则SRP

    前言:上篇C#软件设计——小话设计模式原则之:依赖倒置原则DIP简单介绍了下依赖倒置的由来以及使用,中间插了两篇WebApi的文章,这篇还是回归正题,继续来写写设计模式另一个重要的原则:单一职责原则. ...

  3. SQL 语句大全(转载)

    经典SQL语句大全 一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql serv ...

  4. c语言之【#ifdef】

    电脑程序语句,我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码. 1 2 3 #ifdef 语句1     // 程序2 #endif 可翻译为:如果宏定义了语句1则程序2. 作用:我 ...

  5. docfx组件介绍--YamlSerialization

    在docfx中把元数据以yaml的形式保存,在metadata阶段会序列化数据到yaml文件中,在build阶段又需要从yaml文件反序列化出来.在使用过程中,意外发现yamldotnet在处理大量强 ...

  6. [Django 1]安装Django并创建虚拟虚拟环境项目

    1)安装Django 使用pip来安装,命令如下: pip3 install Djangopip install Django(安装到python2)python3 -m pip install Dj ...

  7. Css--深入学习之切角

    本文是作者从别的网站和文章学习了解的知识,简单做了个笔记,想要学习更多的可以参考这里:[css进阶]伪元素的妙用--单标签之美,奇思妙想 带切角的矩形: 该图来源于(奇思妙想) Css代码: .not ...

  8. Hibernate批量处理海量数据的方法

    本文实例讲述了Hibernate批量处理海量数据的方法.分享给大家供大家参考,具体如下: Hibernate批量处理海量其实从性能上考虑,它是很不可取的,浪费了很大的内存.从它的机制上讲,Hibern ...

  9. jsp通过session传递checkbox中的值

    获取checkbox中的值(第一个页面) <% String foodName[]=request.getParameterValues("chioce"); //“chio ...

  10. jQuery animate动画 stop()方法详解~

    一.动画格式: 格式一:jQueryObject.animate( cssProperties, options ) 格式二:$('#id').animate( styles[, duration ] ...