迷你主机做网站服务器,wordpress 做英汉翻译,建公司网站建设明细报价表,手表网站 二手CSP-201803-2-碰撞的小球
解题思路 通过逐秒模拟每个小球的运动#xff0c;并在小球到达线段端点或者与其他小球碰撞时改变其移动方向#xff0c;来计算 t 秒后每个小球的位置。这个问题的关键点在于理解小球的运动和碰撞是独立并且可以预测的#xff0c;所有的碰撞和方向变…CSP-201803-2-碰撞的小球
解题思路 通过逐秒模拟每个小球的运动并在小球到达线段端点或者与其他小球碰撞时改变其移动方向来计算 t 秒后每个小球的位置。这个问题的关键点在于理解小球的运动和碰撞是独立并且可以预测的所有的碰撞和方向变化都在整数时刻发生这是由于所有的小球都开始在偶数位置上线段长度也是偶数。 1. 初始化阶段
读入小球个数 n、线段长度 L 和时间 t。对每个小球读入其初始位置并创建一个 MyBall 结构包含小球的索引index、位置position和移动方向direction这里所有小球初始方向都设为向右即 direction 1。
2. 模拟每一秒的小球运动
对于给定的时间 t程序模拟每一秒小球的运动。每一秒内对于线段上的每一个小球 根据其方向更新位置如果向右移动则位置加一如果向左移动则位置减一。如果小球到达线段的两端位置为 0 或 L则改变其移动方向即向左变向右向右变向左。
3. 碰撞检测与处理
1 碰撞检测
在每一秒钟的小球移动之后需要检查是否有任何小球发生了碰撞。因为小球只能在直线上移动所以碰撞只可能发生在两个小球相遇的情况下即它们有相同的位置。为了检测这种情况需要将所有小球按照它们当前的位置进行排序。这样只需检查排序后的列表中相邻的小球是否占据相同的位置即可因为不会有三个小球同时相撞。对于每对相邻的小球检查它们是否在同一位置。如果是那么这两个小球就发生了碰撞。
2 碰撞处理
当检测到两个小球发生碰撞时它们会交换速度但在这个问题中所有的小球速度大小相同只是方向相反因为不会有三个小球同时相撞所以只检测相邻两个小球即可。处理的方式是改变每个发生碰撞的小球的移动方向。如果一个小球原本向右移动direction 1在碰撞后它应该改变方向向左移动direction 0反之亦然。
4. 输出结果
模拟结束后即过了 t 秒对小球列表按照初始索引进行排序以确保按照输入顺序输出它们的最终位置。输出每个小球最终的位置。
完整代码
#include iostream
#include algorithm
#include vector
using namespace std;struct MyBall
{int index;int position;bool direction; // 0-左 1-右
};
vectorMyBallballList;
int n, L, t, p;bool cmp1(MyBall a, MyBall b) { // 按位置排序return a.position b.position;
}bool cmp2(MyBall a, MyBall b) { // 按索引排序return a.index b.index;
}int main() {cin n L t;for (int i 0; i n; i){cin p;ballList.push_back({ i,p,1 });}for (int i 0; i t; i){for (auto it : ballList) {if (it.direction) it.position; // 向右else it.position--; // 向左if (it.position L || it.position 0) it.direction !it.direction; // 碰撞检测}sort(ballList.begin(), ballList.end(), cmp1); // 排序是因为不会有三个小球同时相撞所以只检测相邻俩小球即可for (int j 0; j ballList.size() - 1; j) // 对撞检测{if (ballList[j].position ballList[j 1].position){ballList[j].direction !ballList[j].direction;ballList[j 1].direction !ballList[j 1].direction;}}}sort(ballList.begin(), ballList.end(), cmp2); // 恢复索引升序for (auto it : ballList) {cout it.position ;}return 0;
}