UVA 10881

题目就不再写了,直接开始

【分析】蚂蚁碰撞掉头,其实不用考虑掉头问题,直接让“掉头”等价于“对穿而过”,

然后调换它们的状态(感觉像是障眼法hhh),只要分清楚“谁是谁”。因为“掉头”,所以蚂蚁

的相对顺序是不变的,因此把所有目标位置从小到大排序,则从左到右的每个位置都对应初始

状态的每只蚂蚁的位置。由于原题中每只蚂蚁不一定按照从左到右顺序输入,还需要预处理

计算输入中的第i只蚂蚁的序号order[i] 。

【代码】

//2019.4.21 蚂蚁
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 10000 + 5;
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];

const char dirName[][10] = { "L","Turning","R" };

int order[maxn];//输入第i只蚂蚁是终态中左数第order[i]只蚂蚁

int main()
{
    int k;
    scanf_s("%d", &k);
    for (int kase = 1; kase <= k; kase++)
    {
        int L, T, n;
        cout << "Case #" << k << ":
";
        scanf_s("%d%d%d", &L, &T, &n);
        for (int i = 0; i < n; i++)
        {
            int p, d;
            char c;
            scanf_s("%d %c", &p, &c);
            d = (c == 'L' ? -1 : 1);
            before[i] = { i,p,d };
            after[i] = { 0,p + T*d,d };//这里id是未知的
        }
        //分清楚对穿后谁是谁,order数组对应的映射关系
        sort(before, before + n);
        for (int i = 0; i < n; i++)
            order[before[i].id] = i;
        //计算终态
        sort(after, after + n);//“对穿而过”
        for (int i = 0; i < n - 1; i++)//修改碰撞中的蚂蚁的方向
            if (after[i].p == after[i + 1].p)
                after[i].d = after[i + 1].d = 0;
        //输出结果
        for (int i = 0; i < n; i++)
        {
            int a = order[i];
            if (after[a].p<0 || after[a].p>L)
                cout << "Fell off
";
            else
                cout << after[a].p << " " << dirName[after[a].d + 1] << "
";
        }
        cout << "
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cjwen/p/10752599.html