《Python—每日一道算法题》蚂蚁(Piotr‘s Ants,UVa 10881)

题目描述

一根长度为L厘米的木棍上有n只蚂蚁,每只蚂蚁要么朝左爬,要么朝右爬,速度为1厘米/秒。
当两只蚂蚁相撞时,二者同时掉头(掉头时间忽略不计)。
给出每只蚂蚁的初始位置和朝向,计算T秒之后每只蚂蚁的位置。
输入格式
输入的第一行为数据组数。每组数据的第一行为3个正整数L,T,n(0<=n<=10000);
以下n行每行描述一致蚂蚁的初始位置,其中整数x为蚂蚁距离木棍左端的距离,字母表示初始朝向(L表示左,R表示右)
输出格式
对于每组数据输出n行,按输入顺序输出每只蚂蚁的位置和朝向(Turning表示正在碰撞)。在第T秒之前已经掉下木棍的蚂蚁(正好爬到木棍边缘的不算)输出Fell off。

分析:

假设在远处观察这些蚂蚁的运动,会看到什么?一群密密麻麻的小黑点在移动。由于黑点太小,所以当蚂蚁因碰撞而掉头时,看上去和两个点“对穿而过”没有任何区别。

如果把蚂蚁看成没有区别的小点,那么只需独立计算出每只蚂蚁在T时刻的位置即可。

比如,有3只蚂蚁,蚂蚁1=(1,R),蚂蚁2=(3,L),蚂蚁3=(4,L)。则两秒钟之后,3只蚂蚁分别为(3,R),(1,L)和(2,L)。

虽然从整体上讲,“掉头”等价于“对穿而过”,但对于每只蚂蚁而言并不是这样。

蚂蚁1初始状态为(1,R),因此一定有一只蚂蚁在两秒钟之后处于(3,R)的状态,但这只蚂蚁却不一定是蚂蚁1。需要搞清楚目标状态中“谁是谁”。

所有蚂蚁的相对顺序是保持不变的,因此把所有目标位置从小到大排序,则从左到右的每个位置对应于初始状态下从左到右的每只蚂蚁。

但蚂蚁不一定按照从左到右的顺序输入,还需要预处理计算出输入中的第i只蚂蚁的序号order[i]。

Python代码:(这个代码写的有些复杂,不够优雅)

before=[[]]*10000
after=[[]]*10000
#方向
dirName=["L","Turning","R"]
order=[0]*10000#输入的第i只蚂蚁是终态中的左数第order[i]只蚂蚁
K=int(input())
for k in range(1,K+1):
    print(f"Case {k}")
    L,T,n=map(int,input().split())
    for i in range(n):
        #P代表位置,C代表朝向
        INPUT=input().split()
        p,c=int(INPUT[0]),INPUT[1]
        #d朝向,-1左,1右
        d=(-1 if c=='L' else 1)
        before[i]=[i,p,d]#i代表输入顺序
        after[i]=[0,p+T*d,d]#这里的id是未知的
    
    before=[x for x in before if x]
    before.sort(key=lambda x: x[1])
    # print(before)

    for i in range(n):
        order[before[i][0]]=i
    #计算终态
    after=[x for x in after if x]
    after.sort(key=lambda x: x[1])
    for i in range(n-1):#修改碰撞中蚂蚁的方向
        if after[i][1]==after[i+1][1]:
            after[i+1][2]=0
            after[i][2]=0
    #输出结果
    print(f"Case {k} :输出")
    for i in range(n):
        a=order[i]
        if(after[a][1]<0) or (after[a][1]>L):
            print("Fell off")
        else:
            print(after[a][1],dirName[after[a][2]+1])
    print("\n")

运行结果:

猜你喜欢

转载自blog.csdn.net/qq_41251963/article/details/110003079