题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&page=show_problem&problem=1822
题目意思:有一条 L 厘米长的杆,上面有 n 只蚂蚁,给出每只蚂蚁的朝向以及离杆上最左端的距离,问 T 秒之后每只蚂蚁到达的位置,如果 T 秒后某个位置有多只蚂蚁同时到达,那么这堆蚂蚁处于的位置 + Turning,如果超过这条杆的长度,输出Fell off,其余情况是:蚂蚁位置+朝向
突发奇想,想做下这题,学习了 lrj 写法。
他的before 和 after 处理,使得蚂蚁在杆子上依次从左到右处理,而且这样做的好处是,不需要对当前的蚂蚁T秒后的位置与已经处理的蚂蚁作比较(检查是否有Turning 情况),大大节省了时间,否则有可能是10000 × 10000 呢~~~order 数组则记下原来最开始时蚂蚁的编号,是为了输出按回原输入啦。
好简洁,好好向他学习^_^
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std; const int maxn = + ; struct Ant
{
int id; // 蚂蚁编号
int p; // 蚂蚁位置
int d; // 蚂蚁朝向 左: -1 转向:0 右:1
bool operator < (const Ant& a) const
{
return p < a.p;
}
}before[maxn], after[maxn]; int order[maxn];
char dirname[][] = {"L", "Turning", "R"}; int main()
{
int N, L, T, n;
while (scanf("%d", &N) != EOF)
{
for (int cas = ; cas <= N; cas++)
{
scanf("%d%d%d", &L, &T, &n);
int dir;
char pos;
for (int i = ; i < n; i++)
{
cin >> dir >> pos;
int d = (pos == 'R' ? : -);
before[i] = (Ant){i, dir, d};
after[i] = (Ant){, dir+d*T, d};
}
sort(before, before+n);
for (int i = ; i < n; i++)
order[before[i].id] = i;
sort(after, after+n);
for (int i = ; i < n-; i++)
{
if (after[i].p == after[i+].p)
after[i].d = after[i+].d = ; // 碰撞
}
printf("Case #%d:\n", cas);
for (int i = ; i < n; i++)
{
int a = order[i];
if (after[a].p < || after[a].p > L)
printf("Fell off\n");
else
printf("%d %s\n", after[a].p, dirname[after[a].d+]); // +1是因为数组下标没有-1
}
puts("");
}
}
return ;
}