UVa10881蚂蚁

题目链接:点击这里
这是一道很有意思的题。如果我们完全按照题意,最simple的想法就是把每个蚂蚁的位置用数组表示,然后每一时刻就更新位置。这种方法固然可行,但实现起来较为麻烦,而且我们并不需要蚂蚁的中间过程位置,浪费时间。
如果我们把例题中的每一秒的蚂蚁位置画出来,不难发现:
其蚂蚁的相对位置始终是不变的。也就是说,如果蚂蚁B最开始处于蚂蚁A或者蚂蚁C之间,最终的位置只有两种情况:1.fell off,2.仍然处于这两者之间。
从整体上讲,题意中的“掉头”和“穿墙而过”并没有任何区别,但对于单个蚂蚁来说是有变化的。因此,我们需要记录的是蚂蚁的相对顺序。例如,A的位置为(3,R),B的位置为(4,L),“穿墙”之后的位置分别为(4,R),(3,L),按照A、B的相对位置不变可知,A目前的位置为(3,L),B为(4,R),与题意相符。
代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int Length;
int Time;
int Number;
const int maxn = 10000 + 5;

struct ant
{
    int status;//1 stands for right, -1 stands for left,0 stands for turning
    int pos;
    int id;
    ant(int s,int p,int d)
    {
        status = s;
        pos = p;
        id = d;
    }
    ant(){};
    bool operator < (const ant& a)const
    {
        return pos < a.pos;
    }
} before[maxn],after[maxn];

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

int order[maxn];//输入的第i只蚂蚁是排序后的order[i]只蚂蚁

int main()
{
    int n;
    cin>>n;
    for (int kase = 1;kase <= n;kase++)
    {
        cin>>Length>>Time>>Number;
        for (int i = 0; i < Number; i++)               //输入
        {
            int p;
            char ch;
            cin>>p>>ch;
            if (ch == 'R')
            {
                before[i] = ant(1,p,i);
                after[i] = ant(1,p+Time,0);//id not known yet
            }
            else//left
            {
                before[i] = ant(-1,p,i);
                after[i] = ant(-1,p-Time,0);//id not known yet
            }
        }

        sort(before,before+Number);
        for (int i = 0; i < Number; i++)
        {
            order[before[i].id] = i;
        }

        sort(after,after+Number);
        for (int i = 0; i < Number-1; i++)
        {
            if (after[i].pos == after[i+1].pos)
                after[i].status = after[i+1].status = 0;//Turining status
        }


        cout<<"Case #"<<kase<<":"<<endl;
        for (int i = 0 ;i < Number;i++)
        {
            int a = order[i];
            if (after[a].pos < 0 || after[a].pos > Length)
                cout<<"Fell off"<<endl;
            else
            {
                cout<<after[a].pos<<" "<<dirName[after[a].status+1]<<endl;
            }
        }
        cout<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值