试题编号: | 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为偶数。 |
思路:先处理运动,再处理相撞
小球都在坐标轴上x=0右边运动,有n个不计体积的小球在线段上,开始时所有的小球都处在偶数坐标上,速度方向向右,速度大小为1单位长度每秒。 因此可以选择用结构体存储小球的坐标以及方向。小球相撞发生在两个小球坐标相同方向相反的时候, 为了找出相撞的情形,可以直接排序,只可能是相邻的两个球相撞。输出时是按照输入顺序,所以添加一个成员变量id排序后方便输出
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const int N = 1e3+5;
struct Node {
int x,id,dir;
Node() {}
Node(int a,int b,int c):x(a),id(b),dir(c) {}
};
Node b[N];
bool cmp1(Node& a,Node& b) {
return a.x<b.x;
}
bool cmp2(Node& a,Node& b) {
return a.id<b.id;
}
void getNewPosition(Node& a,const int L) {
if(a.x==L) {
a.x=L-1;
a.dir=-1;
} else if(a.x==0) {
a.x=1;
a.dir=1;
} else if(a.dir==1) {
a.x++;
} else if(a.dir==-1) {
a.x--;
}
}
void changeDir(Node& a,Node& b) {
a.dir*=-1;
b.dir*=-1;
}
int main() {
int n,L,t,x;
scanf("%d%d%d",&n,&L,&t);
for(int i=0; i<n; i++) {
scanf("%d",&x);
b[i]=Node(x,i,1);
}
sort(b,b+n,cmp1);
for(int i=0; i<t; i++) {
for(int j=0; j<n; j++) {
getNewPosition(b[j],L);
}
for(int j=0; j<n-1; j++) {
if(b[j].x==b[j+1].x&&b[j].dir!=b[j+1].dir) {
changeDir(b[j],b[j+1]);
}
}
}
sort(b,b+n,cmp2);
for(int i=0; i<n; i++) {
if(i) printf(" ");
printf("%d",b[i].x);
}
return 0;
}