题目链接:
题目大意:
一根长度为 L 厘米的木棍上有 n 只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为 1 厘米/秒。当两只蚂蚁相撞时,二者同时调头(掉头用的时间忽略不计)。给出每只蚂蚁的初始位置和朝向,计算 T 秒之后每只蚂蚁的位置。
题目分析:如《信息竞赛入门经典》中所述,由于掉头用的时间可以忽略不计,所以可以直接看做两只蚂蚁对穿而过。于是可以很开心的直接把坐标按照方向进行加 / 减的处理。得到某只蚂蚁的最终坐标。
把棍子拉为无限长,然后通过模拟这个过程可以发现,蚂蚁的顺序是绝对的,最左边的蚂蚁绝不可能爬到其他蚂蚁的右边去。所以将最终坐标从小到大排序就能够得到这只蚂蚁最终的位置。当然,如果最终蚂蚁的位置坐标小于 0 或者大于 L 那么就直接判断为Fell off。
此外,从题目所给的数据可以看得出,蚂蚁并不是按照顺序输出的,因此用数组存下输入的顺序就OK了。
P.S : 注意每组数据之间有个空行。
代码:
#include <cstdio> #include <algorithm> #include <vector> using namespace std; struct Ant { int enter_order, position, state; Ant (int e, int p, int s) { enter_order = e; position = p; state = s; } }; const int maxn = 10000 + 5; int order[maxn]; // 输入的第i只蚂蚁是队列中左数第order[i]只 int l, t, n; int cases; const char state[][10] = {"L", "Turning", "R"}; bool comp (Ant a1, Ant a2) { return a1.position < a2.position; } int main() { int i, j; int position, direction; char d; scanf("%d", &cases); for (i = 0; i < cases; i++) { vector<Ant> ini_ant, fin_ant; scanf("%d %d %d", &l, &t, &n); for (j = 0; j < n; j++) { scanf("%d %c", &position, &d); direction = (d == 'L' ? -1 : 1); Ant a1(j, position, direction); int new_position = position + t * direction; Ant a2(0, new_position, direction); ini_ant.push_back(a1); fin_ant.push_back(a2); } // 计算order数组 sort(ini_ant.begin(), ini_ant.end(), comp); for (j = 0; j < n; j++) order[ini_ant[j].enter_order] = j; // 对最终状态按照位置进行排序 sort(fin_ant.begin(), fin_ant.end(), comp); for (j = 0; j < n-1; j++) if (fin_ant[j].position == fin_ant[j+1].position) fin_ant[j].state = fin_ant[j+1].state = 0; // 输出每只蚂蚁的对应结果 printf("Case #%d:\n", i + 1); for (j = 0; j < n; j++) { int p = order[j]; if (fin_ant[p].position < 0 || fin_ant[p].position > l) printf("Fell off\n"); else printf("%d %s\n", fin_ant[p].position, state[fin_ant[p].state + 1]); } printf("\n"); } return 0; }
作者:a1006570862 发表于2013-11-21 22:58:40 原文链接
阅读:67 评论:0 查看评论