http://gdutcode.sinaapp.com/problem.php?cid=1105&pid=6
Description
田所前辈正在跳舞(指新宝岛)。
他变出了他自己的N个分身,并成正N边形分布。
他本身处于这个正N边形的中心,正N边形的边长为A。
每个分身都会朝顺时针方向下一个分身以一个相同的固定的速度V移动 移动方向会随着下一个分身的位置变化而变化,最终所有分身都将到达正N边形的中心 也就是回到田所前辈本身,结束。
先辈邀请你去他家,想问你怎么计算每次表演需要多少时间。
Input
多组数据,到EOF结束。
每组数据占一行,有三个整数N,A,V,分别表示:
每次表演的分身个数,分身分布的正N边形的边长,每个分身移动的速度。
N ≤ 300 , A ≤ 400000 , V ≤ 10000 , 答案 ≤ 10000000 , 数据组数 ≤ 10
Output
每组数据一个实数,表示最后一个分身到达本身的时间,保留小数点后5位。
Sample Input
3 10 5
Sample Output
1.33333
运用了物理的正交分解思想,转化为追击问题,十分难想,对于我这等物理渣渣。
首先读题,每个分身时刻向着下一个分身的方向,然后就是很多要发挥想象的东西了。
1.到最后所有分身一定是同一时刻回去的
2.每一个分身的轨迹实际上是螺旋形
3.任意一个时刻正n边形形状不会改变,只是一直在缩小
4.任意时刻每一个分身处于一个同心圆上,圆心是本体
接着有两种思路:
法1:
取任意一个分身和他的下一个分身,易知这两个分身相遇的时刻就是所有分身汇于一点的时刻,于是就要求这两点相遇的时间。由于任意时刻n边形形状不变,故任意两个分身相对角度不变。取两点A和B,将B的速度分解为一个位于A追B的路径,另一个垂直于这个路径,问题相当于在直线上A追B,具体见图。
#include<cstdio>
#include<cmath>
using namespace std;
#define pi (acos(-1))
int n,a,v;
int main()
{
while(scanf("%d%d%d",&n,&a,&v)!=EOF)
{
double t=a/(v*(1-cos(360.0/n/180*pi)));
printf("%.5f\n",t);
}
return 0;
}
法2:
将这个正n边形想象为一个圆,到最后汇于一点的过程相当于这个圆不断缩小。任意时刻n个分身相对位置不变,任取一点,将其速度分解为一个指向n边形中心,另一个垂直于上一条分速度(实际上就是圆的切线),则问题转化为n边形某一点到中心直线时间
#include<cstdio>
#include<cmath>
using namespace std;
#define pi (acos(-1))
double s,t;
int n,a,v;
int main()
{
while(scanf("%d%d%d",&n,&a,&v)!=EOF)
{
s=sqrt((long long)a*a/2.0/(1-cos(2*pi/n)));
t=s/v/(cos(pi*(n-2)/2/n));
printf("%.5f\n",t);
}
return 0;
}