一、问题链接
二、思路
模拟
将小球按输入的先后顺序编号,记录所有小球的编号及坐标。
将所有小球按坐标从小到大排序,碰撞只能发生在相邻的两个小球之间。当小球发生碰撞或到达线段边界时改变方向。
模拟每一秒小球的运动(即运动方向及坐标),模拟t秒之后,将小球按编号再次排序,输出各自的坐标。
三、参考代码
#include <bits/stdc++.h>
using namespace std;
struct Ball {
//loc:坐标
//dir:方向1代表向右,-1代表向左
//num:球的编号
int loc,dir,num;
Ball(int a, int b,int c): loc(a),dir(b),num(c) {}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n,l,t;
cin>>n>>l>>t;
vector<Ball> v;
int temp;
for(int i=0; i<n; i++) {
cin>>temp;
//默认方向为向右,按输入顺序给球进行编号
v.push_back(Ball(temp,1,i+1));
}
//按球所在的坐标从小到大排序
sort(v.begin(),v.end(),[](const Ball& b1,const Ball& b2){
return b1.loc<b2.loc;
});
while(t--) {
for(int i=0; i<v.size(); i++) {//遍历所有的球
if(v[i].loc==0 or v[i].loc==l) { //到边界
v[i].dir*=-1;//改变方向
}
//只可能是相邻坐标的球相互碰撞,vector数组中的元素已经按坐标从小到大排序
else if(i<=v.size()-2 and v[i].loc==v[i+1].loc) { //碰撞
v[i].dir*=-1;//改变方向
v[i+1].dir*=-1;//改变方向
}
v[i].loc+=v[i].dir;//移动
}
}
//按球编号从小到大排序
sort(v.begin(),v.end(),[](const Ball& b1,const Ball& b2){
return b1.num<b2.num;
});
for(auto &i : v) {
cout<<i.loc<<" ";
}
return 0;
}