B

题目链接: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
", x[i]);
49 }

BY 区彦开

原文地址:https://www.cnblogs.com/scnuacm/p/3209964.html