西电复试之——CCF201803-02 碰撞的小球 满分
很有意思的一道题
题目见链接
#include<iostream>
using namespace std;
int sudu[101] = { };
int p[101] = {};
int main() {
int n, L, t;
cin >> n >> L >> t;
//规定速度方向向右为1
for (int i = 0; i < n; i++) {
cin >> p[i];
sudu[i] = 1;
if (p[i] == 0 || p[i] == L) sudu[i] = -sudu[i];
}
for (int i = 0; i < t; i++) {
//在端点换方向
for (int j = 0; j < n; j++) {
p[j] = p[j] + sudu[j];
if (p[j] == 0 || p[j] == L) sudu[j] = -sudu[j];
}
for (int j = 0; j < n; j++) {
for (int k = j + 1; k < n; k++) {
if (p[k] == p[j]) {
sudu[j] = -sudu[j];
sudu[k] = -sudu[k];
}
}
}
}
for (int i = 0; i < n; i++) {
cout << p[i] << " ";
}
return 0;
}
一开始写错了,是因为审题不清楚,错认为,输入的小球顺序是有序的
借鉴大佬的:解决了我上述问题,加一个结构体数组,记录id,然后排序,思想碰撞很舒服
结构体数组排序解法
#include<iostream>
using namespace std;
#include<algorithm>
const int N = 100;
struct node {
int id;
int pos;
int step;
}b[N];
bool cmp1(node a,node b)
{
return a.pos < b.pos;
}
bool cmp2(node a, node b) {
return a.id < b.id;
}
int main() {
int n, l, t, id = 0;
cin >> n >> l >> t;
for (int i = 0; i < n; i++) {
b[i].id = ++id;
cin >> b[i].pos;
// 开始往右走,到达两端则回头
b[i].step = 1;
if (b[i].pos == l || b[i].pos == 0)
b[i].step = -b[i].step;
}
sort(b, b + n, cmp1);
for (int i = 0; i < t; i++) {
// 走一步
for (int j = 0; j < n; j++) {
b[j].pos += b[j].step;
// 到达两端则回头
if (b[j].pos == l || b[j].pos == 0)
b[j].step = -b[j].step;
}
// 判断是否碰头,碰头则掉头(排序后只需要比较相邻的)
for (int j = 1; j < n; j++)
if (b[j].pos == b[j - 1].pos)
b[j].step = -b[j].step, b[j - 1].step = -b[j - 1].step;
}
sort(b, b + n, cmp2);
for (int i = 0; i < n; i++)
cout << b[i].pos << " ";
return 0;
}