2016 Multi-University Training Contest 8-1006 physics:http://acm.hdu.edu.cn/showproblem.php?pid=5826
题目描述:
physics
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 566 Accepted Submission(s): 359
Problem Description
There are n balls on a smooth horizontal straight track. The track can be considered to be a number line. The balls can be considered to be particles with the same mass.
At the beginning, ball i is at position Xi. It has an initial velocity of Vi and is moving in direction Di.(Di∈−1,1)
Given a constant C. At any moment, ball its acceleration Ai and velocity Vi have the same direction, and magically satisfy the equation that Ai * Vi = C.
As there are multiple balls, they may collide with each other during the moving. We suppose all collisions are perfectly elastic collisions.
There are multiple queries. Each query consists of two integers t and k. our task is to find out the k-small velocity of all the balls t seconds after the beginning.
* Perfectly elastic collision : A perfectly elastic collision is defined as one in which there is no loss of kinetic energy in the collision.
At the beginning, ball i is at position Xi. It has an initial velocity of Vi and is moving in direction Di.(Di∈−1,1)
Given a constant C. At any moment, ball its acceleration Ai and velocity Vi have the same direction, and magically satisfy the equation that Ai * Vi = C.
As there are multiple balls, they may collide with each other during the moving. We suppose all collisions are perfectly elastic collisions.
There are multiple queries. Each query consists of two integers t and k. our task is to find out the k-small velocity of all the balls t seconds after the beginning.
* Perfectly elastic collision : A perfectly elastic collision is defined as one in which there is no loss of kinetic energy in the collision.
Input
The first line contains an integer T, denoting the number of testcases.
For each testcase, the first line contains two integers n <= 10^5 and C <= 10^9.
n lines follow. The i-th of them contains three integers Vi, Xi, Di. Vi denotes the initial velocity of ball i. Xi denotes the initial position of ball i. Di denotes the direction ball i moves in.
The next line contains an integer q <= 10^5, denoting the number of queries.
q lines follow. Each line contains two integers t <= 10^9 and 1<=k<=n.
1<=Vi<=10^5,1<=Xi<=10^9
For each testcase, the first line contains two integers n <= 10^5 and C <= 10^9.
n lines follow. The i-th of them contains three integers Vi, Xi, Di. Vi denotes the initial velocity of ball i. Xi denotes the initial position of ball i. Di denotes the direction ball i moves in.
The next line contains an integer q <= 10^5, denoting the number of queries.
q lines follow. Each line contains two integers t <= 10^9 and 1<=k<=n.
1<=Vi<=10^5,1<=Xi<=10^9
Output
For each query, print a single line containing the answer with accuracy of 3 decimal digits.
Sample Input
1 3 7 3 3 1 3 10 -1 2 7 1 3 2 3 1 2 3 3
Sample Output
6.083 4.796 7.141
题目大意:
实数轴上有n个小球,给定小球的初速度,且给定每时每刻小球的初速度和加速度的方向一致且乘积都是常数C,即两者满足反比例函数关系,且小球一直都在加速;给定每只小球的初始位置和初速度方向,求经过t秒之后,所有的小球中速度第k小的小球的速度为多少。
算法实现:
由于每个小球都在同一条直线上运动,则难免发生碰撞,且在整个碰撞的过程中满足完全弹性碰撞,且满足动量守恒和能量守恒,且每个小球的质量一样,所以在每次碰撞过程中,发生碰撞的两个小球(相对或者同向)之间都是交换彼此的速度大小,而速度方向或与原来相反,或与原来相同,这样就可以看成是两个小球直接穿过了对方,所以,对于每个小球的初始位置和初始方向并不需要管。通过找规律可以得到(常规方法是积分,但是比较难积,所以就去找规律了):
经过正规的积分可以得到:
该试即可以得出在t秒时的速度之和初速度变量有关,所以,我们可以通过初速度的大小先判断出来谁是第k小的速度,再求得第k小的末速度,这样可以降低时间复杂度,不会超时。
代码实现:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
long long v[100100];
int main()
{
long long t,n,c,q,T,k;
scanf("%d",&T);
while(T--)
{
memset(v,0,sizeof(v));
scanf("%lld%lld",&n,&c);
int x,d;
for(int i=0;i<n;i++)
{
scanf("%lld%lld%lld",&v[i],&x,&d);
}
sort(v,v+n);
scanf("%lld",&q);
for(int i=0;i<q;i++)
{
scanf("%lld%lld",&t,&k);
double res=sqrt((double)(v[k-1]*v[k-1]+2*t*c));
printf("%.3lf\n",res);
}
}
return 0;
}