【Codeforces Round 330 (Div 2)D】【计算几何 二分答案】Max and Bike 最小骑车距离使得圆上传感器很坐标位移为dis

D. Max and Bike
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

For months Maxim has been coming to work on his favorite bicycle. And quite recently he decided that he is ready to take part in a cyclists' competitions.

He knows that this year n competitions will take place. During the i-th competition the participant must as quickly as possible complete a ride along a straight line from point si to point fi (si < fi).

Measuring time is a complex process related to usage of a special sensor and a time counter. Think of the front wheel of a bicycle as a circle of radius r. Let's neglect the thickness of a tire, the size of the sensor, and all physical effects. The sensor is placed on the rim of the wheel, that is, on some fixed point on a circle of radius r. After that the counter moves just like the chosen point of the circle, i.e. moves forward and rotates around the center of the circle.

At the beginning each participant can choose any point bi, such that his bike is fully behind the starting line, that is, bi < si - r. After that, he starts the movement, instantly accelerates to his maximum speed and at time tsi, when the coordinate of the sensor is equal to the coordinate of the start, the time counter starts. The cyclist makes a complete ride, moving with his maximum speed and at the moment the sensor's coordinate is equal to the coordinate of the finish (moment of time tfi), the time counter deactivates and records the final time. Thus, the counter records that the participant made a complete ride in time tfi - tsi.

【Codeforces Round 330 (Div 2)D】【计算几何 二分答案】Max and Bike 最小骑车距离使得圆上传感器很坐标位移为dis_第1张图片

Maxim is good at math and he suspects that the total result doesn't only depend on his maximum speed v, but also on his choice of the initial point bi. Now Maxim is asking you to calculate for each of n competitions the minimum possible time that can be measured by the time counter. The radius of the wheel of his bike is equal to r.

Input

The first line contains three integers n, r and v (1 ≤ n ≤ 100 000, 1 ≤ r, v ≤ 109) — the number of competitions, the radius of the front wheel of Max's bike and his maximum speed, respectively.

Next n lines contain the descriptions of the contests. The i-th line contains two integers si and fi (1 ≤ si < fi ≤ 109) — the coordinate of the start and the coordinate of the finish on the i-th competition.

Output

Print n real numbers, the i-th number should be equal to the minimum possible time measured by the time counter. Your answer will be considered correct if its absolute or relative error will not exceed 10 - 6.

Namely: let's assume that your answer equals a, and the answer of the jury is b. The checker program will consider your answer correct if .

Sample test(s)
input
2 1 2
1 10
5 9
output
3.849644710502
1.106060157705


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=0,M=0,Z=1e9+7,ms63=1061109567;
const double PI=acos(-1.0);
int main()
{
	int n,R,V;
	while(~scanf("%d%d%d",&n,&R,&V))
	{
		double C=2*PI*R;
		for(int i=1;i<=n;++i)
		{
			int st,ed;
			scanf("%d%d",&st,&ed);
			double dis=ed-st;
			double ans=0;
			int k=dis/C;
			dis-=k*C;dis/=2;
			ans+=k*C;
			double l=0;
			double r=dis;
			for(int tim=1;tim<=100;++tim)
			{
				double m=(l+r)/2;
				//double ang=m/R;
				//double tmp=m+R*sin(ang);
				m+R*sin(m/R)>=dis?r=m:l=m;
			}
			printf("%.15f\n",(ans+2*l)/V);
		}
	}
	return 0;
}
/*
【题意】
有n(1e5)次比赛,
我们有一个半径大小为r(1e9)的圆,转速为v(1e9)。
对于每次比赛,我们告诉你第i次比赛 起点和最si和终点f。
我们可以在每次比赛之前,确定传感器在圆上的位置。
传感器的横坐标到达si位置的时间被认定为初始时间
传感器的横坐标到达ti位置的时间被认定为终止时间
问你,如何在比赛前选择传感器的位置,可以使得我们完成比赛的时间尽可能短。
输出这个最短时间。

【类型】
二分

【分析】
首先,这是一个圆。
很显然地,为了使得最优,比赛开始和比赛结束时传感器的圆上位置,要求必须是恰好对称的。
于是比赛中间时间,传感器的位置就必然是在这个圆的正上方或者正下方。
因为题目要求时间尽可能短,所以传感器的位置实际上是在圆的正上方(结合公式,发现正上方有加成)

然后,如果路径长度是圆周的k倍,那么无论这个传感器初始设置在哪里,都会恰好在圆上经过k圈。
于是,我们可以首先计数这一开始的圈数入答案中。

这里要提出一个技巧。
因为我计算几何超级差!所以让我直接求这个传感器的横坐标与总运动距离的关系,简直是要命>_<
于是,要想办法转化——
一个圆在平地上滚动,哪里可以作为参考点呢?显然就是圆心。
一个圆的的位移量为dis,那么这个圆的圆心的位移量也显然为dis。
而这个传感器的位置,就可以通过与圆心的位置关系求出。

我们已经把问题处理到只剩下了最多一个圆。
在"传感器由圆的最上方,圆滚动,传感器达到圆的最下方"这个过程中——
传感器的位移量,总是大于等于圆的位移量。而且公式都可以写成——
位移量(传感器)==dis+ r*sin(α),其中α为圆的位移偏角,α= (dis/r)
即:我们想要求圆心的最小的位移量为多少,设这个最小位移量为dis。
那么dis+r*sin(dis/r)=某个已知量。
我们要怎么求dis呢?反过来求很难。
但是dis和这个已知量之间,是存在同样的单调性的。
于是我们二分答案,使得等号右边恰好等于这个已知量。

答案也就求出来啦,啦啦啦啦!
~\(≧▽≦)/~

【时间复杂度&&优化】
O(nlogn)

【数据】
2 1 2
5 9
*/


你可能感兴趣的:(codeforces,二分,计算几何-圆,题库-CF)