Problem F chino with ball
题意:
在一条无穷远的直线上的一些位置上存在若干个相同的小球,每个小球在起始时间时存在三个状态:向左1m/s,向右1m/s,不动。现在请你求出在k秒后每个小球的位置(小球间的碰撞符合完全弹性碰撞)。
知识点:
模拟、数学思想
题解:
因为每个小球都符合完全弹性碰撞,所以先假定每个小球单独在直线上进行运动,这时每个小球在k秒后到达的位置,在实际中所有小球运动完之后肯定存在一个小球(在完全弹性碰撞的作用下只会改变每个位置上到达的小球的编号,但这个位置上存在小球是定值)。其次,又因为碰撞的原因,每个小球在起始位置上的顺序不会发生改变(一个小球无法越过另一个小球)。根据这两个不变的值我们便能得到答案。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Ball {
ll pos;
ll v;
ll num;
ll dx;
}ball[100010];
bool cmp1(Ball a, Ball b) {
return a.pos < b.pos;
}
bool cmp2(Ball a, Ball b) {
return a.num < b.num;
}
ll n;
ll sec;
int temp[100010];
int main()
{
cin >> n >> sec;
for (int i = 1; i <= n; i ++ ) {
cin >> ball[i].pos >> ball[i].v;
ball[i].num = i;
}
sort(ball + 1, ball + n + 1, cmp1);
for (int i = 1; i <= n; i ++ ) {
ball[i].dx = i;
}
sort(ball + 1, ball + n + 1, cmp2);
for (int i = 1; i <= n; i ++ ) {
temp[i] = ball[i].dx;
}
for (int i = 1; i <= n; i ++ ) {
if (ball[i].v == 1) ball[i].pos += sec;
else if (ball[i].v == -1) ball[i].pos -= sec;
}
sort(ball + 1, ball + n + 1, cmp1);
for (int i = 1; i <= n; i ++ ) {
cout << ball[temp[i]].pos;
if (i < n) cout << " ";
}cout << endl;
return 0;
}