算法竞赛入门经典-训练指南(10881-Piotr's Ants)

题目大意:

一根长度为L的木棍一堆蚂蚁爬,向左或向右,速度都为1,若两蚂蚁碰撞则同时转头(转身时间忽略不计),问T时间之后每只蚂蚁的位置;

输入:t,(t个样例),每个样例输入 L,T,n,接下来是n行每行两个数据,一个POS(位置),一个dir(方向);

输出:按输入顺序输出每只蚂蚁的最终位置,若处于碰撞状态则输出Turning,掉下去输出”Fell off“;

解题思路:

本题类似于《挑战程序设计》的一道水题(POJ -1852  Ants),思路题;不过本题输入并不一定是按照位置大小进行输入的,因此,需要一个order数组进行预处理,具体看代码及注释;

AC代码:

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;


/****************************************************

样例:
2
10 1 4
1 R
5 R
3 L
10 R

****************************************************/

const int maxn = 10000;
struct ant
{
    int  id;                      //输入顺序;
    int pos;                      //实际位置;
    int dir;                      //朝向:
}before[maxn],after[maxn];

bool cmp(ant a,ant b)               //按照位置进行排序
{
    return a.pos<b.pos;
}

const char dire[][10]={"L","Turning","R"};             //数组保存输出结果
int order[maxn];                                       //order数组的作用是保存各蚂蚁终态的相对位置;

int main()
{
    int t1;
    cin>>t1;
    for (int kase=1;kase<=t1;kase++)
    {
        cout<<"Case #"<<kase<<":"<<endl;
        int l,t,n;
        cin>>l>>t>>n;
        for (int i=0;i<n;i++)
        {
            int x;
            char c;
            cin>>x>>c;
            int d=(c=='L'?-1:1);
            before[i]=ant{i,x,d};
            after[i]=ant{0,x+d*t,d};        //朝向依旧是d,因为必有一只蚂蚁的朝向是原来的d,比如(1,R)->(3,R),只不过不知道是那只蚂蚁;
        }
        sort(before,before+n,cmp);
        for (int i=0;i<n;i++)
        {
            order[before[i].id]=i;          //before[i].id 是原来数组的输入顺序,现在before按照位置进行排序,那么此时对应的就是当前位置蚂蚁的编号;
                                            //比如样例中排序后before[1]是位置3的蚂蚁,其顺序为3,那么就是order[3]=2;
                                            //那么样例中的order就是  1 3 2 4;
                                            //之后after数组的输出after[order[1]].pos就是5这个位置的末位置;
        }
        sort(after,after+n,cmp);
        for (int i=0;i<n-1;i++)
        {
            if (after[i].pos==after[i+1].pos)
            {
                after[i].dir=after[i+1].dir=0;
            }
        }
        for (int i=0;i<n;i++)
        {
            int a=order[i];
            if (after[a].pos < 0||after[a].pos>l) cout<<"Fell off"<<endl;
            else
            {
                cout<<after[a].pos<<" "<<dire[after[a].dir+1]<< endl;
            }
        }
        cout<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/SunQi-lvbu/p/7089076.html