本题为CSP认证201803的第二题 ,乍一看题目很难,但是把握了核心点,就很容易
题目说有几个小球,如果碰到边界就会反方向移动,如果撞在一起也会反方向移动
很多个小球情况就会变得特别复杂
但是我们只要运用好制定的两个规则,就可以解决这道题
我们可以定义一个结构体,定义坐标,方向变量,定义方向改变和移动和碰到边界方法
当方向为正向正方向移动,方向为负为负方向移动
当碰到边界调用方向改变方法
int x; // 坐标
int dir; // 方向
int move(){ // 移动
if(dir == 1){
x = x + 1;
}
if(dir == -1){
x = x - 1;
}
}
int is_boder(int l){
if(x == l or x == 0){
reverse();
}
}
int reverse(){
if(dir == -1) dir = 1;
else if (dir == 1) dir = -1;
}
再调用move函数即可
for(int i=0;i<n;i++){
ball[i].move();
}
这样我们完成了第一步,实现了边界回弹
但小球之间的碰撞呢?我们发现如果有两个小球坐标相同,则改变各自的方向
for(int i=0;i<n;i++){ // 坐标一样方向变化
for(int j=i+1;j<n;j++){
if(ball[i].x == ball[j].x){
ball[i].reverse();
ball[j].reverse();
}
}
两个条件都满足了,就算有再多小球,结果自然也是正确的
所有代码如下
#include<iostream>
using namespace std;
struct Ball{
int x; // 坐标
int dir; // 方向
int move(){
if(dir == 1){
x = x + 1;
}
if(dir == -1){
x = x - 1;
}
}
int is_boder(int l){
if(x == l or x == 0){
reverse();
}
}
int reverse(){
if(dir == -1) dir = 1;
else if (dir == 1) dir = -1;
}
}ball[1001];
int main(){
int n,l,t;
cin>>n>>l>>t;
for(int i=0;i<n;i++){
cin>>ball[i].x;
ball[i].dir = 1;
}
for(int i=0;i<t;i++){ // 模拟时间
for(int i=0;i<n;i++){ // 判断是否边界
ball[i].is_boder(l);
}
for(int i=0;i<n;i++){ // 坐标一样方向变化
for(int j=i+1;j<n;j++){
if(ball[i].x == ball[j].x){
ball[i].reverse();
ball[j].reverse();
}
}
}
for(int i=0;i<n;i++){
ball[i].move();
}
}
for(int i=0;i<n;i++){
cout<<ball[i].x<<" ";
}
cout<<endl;
return 0;
}