题意:有很多只蚂蚁在一条直线上,每个蚂蚁移动速度都是1,并且有一个初始方向。并且当相邻两个蚂蚁相撞时转向。现在问t时间后各个蚂蚁的位置。
解法:这题的一个致命技巧就是把两只蚂蚁的相撞看作是两只蚂蚁交换穿过对方并且交换蚂蚁的编号。这个是很好理解的,类似于物理的完全弹性碰撞。又由于任何两只蚂蚁的相对位置在这种转弯的情况下不会改变相对位置,因此我们只要视作所有蚂蚁没有蚂蚁的行动。最后根据位置关系对应到原始的位置关系。最后再做位置判断的时候查看是否超出坐标之外即可。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <iostream> using namespace std; const int INF = 0x7fffffff; int le, ti, n; struct Ant { int pos; int dir; int no; bool operator < (const Ant & other) const { return pos < other.pos; } }e[10005]; int hx[10005]; int main() { int T, ca = 0; char dir[5]; scanf("%d", &T); while (T--) { scanf("%d %d %d", &le, &ti, &n); for (int i = 1; i <= n; ++i) { scanf("%d %s", &e[i].pos, dir); e[i].no = i; e[i].dir = dir[0] == 'L' ? -1 : 1; } e[0].pos = -INF, e[n+1].pos = INF; sort(e+1, e+1+n); for (int i = 1; i <= n; ++i) { hx[e[i].no] = i; // 记录输入顺序和蚂蚁相对顺序的一个映射 e[i].pos += ti * e[i].dir; } sort(e+1, e+1+n); printf("Case #%d:\n", ++ca); for (int i = 1; i <= n; ++i) { int p = hx[i]; if (e[p].pos < 0 || e[p].pos > le) { puts("Fell off"); } else if (e[p].pos == e[p-1].pos || e[p].pos == e[p+1].pos) { printf("%d Turning\n", e[p].pos); } else { printf(e[p].dir == -1 ? "%d L\n" : "%d R\n", e[p].pos); } } puts(""); } return 0; }