弹性碰撞的题目一般都是指碰到就会掉转方向的一类题目,这里我们可以忽略掉头,仅仅看成擦肩而过,交换名字等等
题意:一条线上N只蚂蚁,每只蚂蚁速度固定,方向和坐标不同,碰头后掉头,求最后掉下去那只蚂蚁的名字。
思路:
- 如果只有一只蚂蚁,就可以计算了
- 但是如果题目很多只,这个时候就要用上弹性碰撞题目的解题技巧
- 到最远的那只,确定它前进的方 向
- 找到前进方向有多少只跟其方向相反(即交换了多少次名字)
- 最后交换名字的那一只就是ans
特别主要开始时,要通过position来区分往右还是左
解决题目的代码:
#include <iostream> #include <stdio.h> #include <algorithm> #include <math.h> #include <cstring> #include <vector> #include <queue> #include <string> #include <iomanip> using namespace std; #define maxn 32000+16 struct node { double position; string name; bool operator< (const node other)const { return abs(position) < abs((other.position)); } }ih[maxn]; int main() { int n; while (cin >> n && n) { double l, v; cin >> l >> v; for (int i = 0; i < n; i++) { char pn; cin >> pn >> ih[i].position >> ih[i].name; if (pn == 'n' || pn == 'N') { ih[i].position = -ih[i].position; } } sort(ih, ih + n); //找到最远的点 double max_d = 0.0; int id=0; bool right = true; for (int i = 0; i < n; i++) { double ps = (ih[i].position < 0.0 ? 0 : l) - ih[i].position; if (max_d < ps) { max_d = ps; id = i; right = ih[i].position > 0.0; } } //与这个点方向相反的点有 int count = 0; if (right) { for (int i = id; i < n; i++) { if (ih[i].position < 0.0) count++; } id += count; } else { for (int i = id; i>=0; i--) { if (ih[i].position > 0.0) count++; } id -= count; } double result = max_d / v; cout << setw(13) << fixed << setprecision(2) << (int)(result * 100) / 100.0 << ' ' << ih[id].name << endl; } return 0; }