B - Collisions
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26830#problem/B
题目大意:直线上有n个不计半径的球,有初始坐标和速度,给出公式,问第t秒这些球分别在哪些位置
思路:有点麻烦的水题,大致上就是每次算出两个球相撞的最小时间mint,然后计算出mint秒后球球们分别都在什么位置,相撞的都要计算速度(注意:同一时间可能有多对球同时碰撞,我用一个WA证实了这一点……)。
还有要注意的事,比如速度相等的、位置相同的球不能用来算最小时间,理由自己想。还有算出来时间不是正数也不能要,不是正数说明两个球没外力干扰的情况下永远不会相撞。
AC Code:
1 #include <cstdio> 2 #include <cmath> 3 4 const int MAXN = 110; 5 const double EPS = 1e-6; 6 7 double x[MAXN], v[MAXN]; 8 int m[MAXN]; 9 10 int main() { 11 int n, t; 12 scanf("%d%d", &n, &t); 13 for(int i = 0; i < n; ++i) 14 scanf("%lf%lf%d", &x[i], &v[i], &m[i]); 15 double nowt = 0; 16 while(true) { 17 double mint = 1e10; 18 int ix, jx; 19 for(int i = 0; i < n; ++i) { 20 for(int j = i + 1; j < n; ++j) { 21 if(fabs(v[j] - v[i]) < EPS) continue; 22 double tmpt = (x[i] - x[j]) / (v[j] - v[i]); 23 if(tmpt <= EPS) continue; 24 if(mint > tmpt) { 25 mint = tmpt; 26 //ix = i; jx = j; 27 } 28 } 29 } 30 if(nowt + mint > t) break; 31 else nowt += mint; 32 for(int i = 0; i < n; ++i) { 33 x[i] += v[i] * mint; 34 } 35 for(int i = 0; i < n; ++i) { 36 for(int j = i+1; j < n; ++j) { 37 if(fabs(x[i] - x[j]) > EPS) continue; 38 ix = i; jx = j; 39 double vix = v[ix]; 40 v[ix] = ((m[ix] - m[jx]) * v[ix] + 2 * m[jx] * v[jx]) / (m[ix] + m[jx]); 41 v[jx] = ((m[jx] - m[ix]) * v[jx] + 2 * m[ix] * vix) / (m[ix] + m[jx]); 42 } 43 } 44 } 45 for(int i = 0; i < n; ++i) { 46 x[i] += v[i] * (t - nowt); 47 } 48 for(int i = 0; i < n; ++i) printf("%f\n", x[i]); 49 }
BY 区彦开