ants小蚂蚁

一根长为S厘米的木棍,上面有N只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米/秒。当两只蚂蚁相撞时,二者同时掉头(掉头时间忽略不计)。给出每只蚂蚁的初始位置和朝向,你的任务是计算最后一只蚂蚁从木棍上掉下去的时间及它的初始位置。

Input
输入数据有多组。
第一行两个整数S,N;(1 ≤S≤999),(1 ≤N≤S+1).
接下来N行,表示N个蚂蚁的初始位置,和初始方向。
L为向左,R为向右。

Output
对于每组数据输出一行。
输出最后一只蚂蚁掉下去的时间T,及它的初始位置P(有两只时为P和Q),(P<Q)
ex:“The last ant will fall down in T seconds - started at P.”
如果最后是两只蚂蚁分别在两端同时掉下去,结果为
ex:“The last ant will fall down in T seconds - started at P and Q”.

Sample Input
999 1
0 R
10 1
0 L
14 5
3 L
6 L
13 L
8 R
1 R
Sample Output
The last ant will fall down in 999 seconds - started at 0.
The last ant will fall down in 0 seconds - started at 0.
The last ant will fall down in 13 seconds - started at 6 and 8.
********************************************我是华丽丽的分割线*************************************************************
看到题目,就该考虑两个东西
1,怎么将最后落下来的时间求出来?
答:因为蚂蚁相遇就要掉头,自己画图模拟一下就知道,可以把蚂蚁的相遇掉头问题看成是蚂蚁从对方身体里穿过,因为掉头改变的仅仅是他们的编号,而这里是可以忽略编号的改变,可以看成每只蚂蚁遇到另外的蚂蚁就穿过去,直接奔赴目的地,如下图,如果忽略1、2编号,那么可以看成是直接穿过的,如果该蚂蚁的位置为a,方向为L,那么它要走的距离就是(a),如果是L,那么它掉下去前要走(L-a),1cm/s;只要求出最长距离就知道时间了。

2、怎么知道最后掉下来的是哪一只?
1,最后掉下来的数目,要么就是一只,要么就两只,不可能超过两只,最多就是两个端点同时掉下来;
2,向左向右的蚂蚁数目自始至终都不会改变的,因为就算相遇掉头,也还是一左一右,只是蚂蚁的编号变了,不会改变总的向左向右的数目;
3,左边的蚂蚁最终还是会掉到左边,不会跨过右边的蚂蚁而掉到右边;
4,边上的蚂蚁永远会比中间的蚂蚁先掉,因为要边上的蚂蚁先掉了,中间的蚂蚁才会掉下去。
5,因为向左掉的数目和向右掉的数目确定了,而且左边的蚂蚁只能往左边掉,右边的蚂蚁只能往右边掉,很容易就知道最后掉下的两只了(只能粗略估计会最后掉下去,并不能保证最后是一起掉下去的还是分先后),就是往左掉的最后一只和往右掉的最后一只。

6,因为刚开始求出了最长时间,也知道了那只蚂蚁的方向(那个方向一定是最后掉下的蚂蚁的初始方向),如果最大长度只有一个,那么拿它的方向和最后掉下的那两个判断一下,那个方向相同的,就是最后掉下去的,如果有两个最大长度的话,就把那两个输出,因为他们两个一定是最后掉下的。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct x
{
    int a;
    char b;
    int c;
} hh[1111];
int cmp(x m,x n)
{
    return m.a<n.a;
}
int main ()
{
    int s,n;
    while(scanf("%d%d",&s,&n)!=EOF)
    {
        int a;
        char b;
        int max=-1,c,count=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&hh[i].a);
            getchar();
            scanf("%c",&hh[i].b);
            getchar();
            if(hh[i].b=='R')
            {

                hh[i].c=s-hh[i].a;
            }
            else
            {
                count++;
                hh[i].c=hh[i].a;
            }
            max=max>hh[i].c?max:hh[i].c;
        }
        sort(hh,hh+n,cmp);
        int countt=0,zz,yy;
        for(int i=0; i<=n-1; i++)
        {
            if(max==hh[i].c)
            {
                countt++;
                if(countt==1)
                {
                    if(hh[i].b=='L')
                    {
                        yy=hh[count-1].a;
                    }
                    else
                    {
                        yy=hh[count].a;
                    }

                }
                if(countt==2)
                {
                    if(hh[i].b=='L')
                    {
                        zz=hh[count-1].a;
                    }
                    else
                    {
                        zz=hh[count].a;
                    }
                }
            }
        }
        if(zz>=yy&&countt==2)
        {
            printf("The last ant will fall down in %d seconds - started at %d and %d.\n",max,yy,zz);
        }
        if(zz<yy&&countt==2)
        {
            printf("The last ant will fall down in %d seconds - started at %d and %d.\n",max,zz,yy);
        }
        if(countt==1)
        {
             printf("The last ant will fall down in %d seconds - started at %d.\n",max,yy);
        }
        }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值