试题编号: | 201803-2 |
试题名称: | 碰撞的小球 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 数轴上有一条长度为L(L为偶数)的线段,左端点在原点,右端点在坐标L处。有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。 提示 因为所有小球的初始位置都为偶数,而且线段的长度为偶数,可以证明,不会有三个小球同时相撞,小球到达线段端点以及小球之间的碰撞时刻均为整数。 输入格式 输入的第一行包含三个整数n, L, t,用空格分隔,分别表示小球的个数、线段长度和你需要计算t秒之后小球的位置。 输出格式 输出一行包含n个整数,用空格分隔,第i个整数代表初始时刻位于ai的小球,在t秒之后的位置。 样例输入 3 10 5 样例输出 7 9 9 样例说明 初始时,三个小球的位置分别为4, 6, 8。 样例输入 10 22 30 样例输出 6 6 8 2 4 0 4 12 10 2 数据规模和约定 对于所有评测用例,1 ≤ n ≤ 100,1 ≤ t ≤ 100,2 ≤ L ≤ 1000,0 < ai < L。L为偶数。 |
解题思路:首先得到哪些情况速度会反向,
第一种:球的位置到了两端。
第二种:两个球的位置相等。
接着大概可以想出用while(t--),来描述每一秒每个小球的位置变化,先判断小球位置从而得到速度是1还是-1,然后再计算位置。
第一次代码:
#include <iostream>
using namespace std;
struct qiu{
int site; //位置
int v; //速度
};
int main(){
int n,L,t; //n为球的个数,L为长度(偶数),t为时间
cin>>n>>L>>t;
int i=n,j; //循环变量
struct qiu a[n]; //球的结构数组
while(i--){ //给每个球添加数据
cin>>a[i].site;
a[i].v=1; //初始化速度
}
while(t--){ //时间段内球的数据变化,每次循环的时间段为一秒
for(i=0;i<n;i++){
if(a[i].site==L||a[i].site==0) a[i].v*=-1; //到达左右端点速度变成反向(以向右为正方向)
for(j=0;j<n;j++){
if(a[i].site==a[j].site&&i!=j){ //site值相等且不是同一个球,速度变成反向
a[i].v*=-1;
a[j].v*=-1;
}
}
}
for(i=0;i<n;i++) a[i].site+=a[i].v; //这一秒的位置变化
}
i=0;
while(i!=n) cout<<a[i++].site<<" " ;
return 0;
}
输入这个样例是对的。
但是输入第二个样例出现了错误。
经过一番思考,我发现我有一段代码出现逻辑问题。
while(t--){ //时间段内球的数据变化,每次循环的时间段为一秒
for(i=0;i<n;i++){
if(a[i].site==L||a[i].site==0) a[i].v*=-1; //到达左右端点速度变成反向(以向右为正方向)
for(j=0;j<n;j++){
if(a[i].site==a[j].site&&i!=j){ //site值相等且不是同一个球,速度变成反向
a[i].v*=-1;
a[j].v*=-1;
}
}
}
for(i=0;i<n;i++) a[i].site+=a[i].v; //这一秒的位置变化
}
就是site,位置相等的时候,让速度变成反方向,但是这是一个遍历,就是两个球位置相等时中,for循环到第一个球(两球之一),然后通过第二个for找到第二个球和他位置相等,接着速度反向。然后当第一个for循环到第二个球的时候,第二个for寻到第一个球的时候,又符合条件继续让速度相反,这样就两次对速度进行变更了。
所以我没有考虑好如果两个球位置相等的时候,只循环一次,当第一个for循环到第二个球的时候,将不进入循环找第一个球。
只要在第二个for前设置一个条件即可。但是有可能某一秒有多个球位置相等,所以得用到多个变量,于是我在结构体中增加了一个flag来控制。
第二次代码如下
#include <iostream>
using namespace std;
struct qiu{
int site; //位置
int v; //速度
int flag; //在每秒中当通过循环找到两球位置相等之后,让这个循环停止
};
int main(){
int n,L,t; //n为球的个数,L为长度(偶数),t为时间
cin>>n>>L>>t;
int i=n,j; //循环变量
struct qiu a[n]; //球的结构数组
while(i--){ //给每个球添加数据
cin>>a[i].site;
a[i].v=1; //初始化速度
}
while(t--){ //时间段内球的数据变化,每次循环的时间段为一秒
for(i=0;i<n;i++) a[i].flag=1;
for(i=0;i<n;i++){
if(a[i].site==L||a[i].site==0) a[i].v*=-1; //到达左右端点速度变成反向(以向右为正方向)
if(a[i].flag) //判断是否可以进入循环寻找相同位置的球 ,已经找到过就无法进入
for(j=0;j<n;j++){
if(a[i].site==a[j].site&&i!=j){ //site值相等且不是同一个球,速度变成反向
a[i].v*=-1;
a[j].v*=-1;
a[j].flag=0; //找到相同位置的球之后停止这秒内相同位置的另一个球进入这个循环
}
}
}
for(i=0;i<n;i++){
a[i].site+=a[i].v; //这一秒的位置变化
}
}
while(n--) cout<<a[n].site<<" " ;
return 0;
}
编译后通过。