【2020 kick start round B】python 解题思路

时差问题,没在round B开始的第一时间爬起来,但好在还是在开始一个半小时后爬起来了。。总之,感觉题目比全年年底简单好多诶,但还是不能全部AC。在此记录我AC的方法,以及我看到的让人拍案叫绝的方法。
题目1 寻找数列中的peak
题目简述:数列中,当前一个元素同时大于它之前之后的元素,则认为该元素为数列中的一个peak;peak中不包括第一个和最后一个元素,问给定数列,输出peak个数。

比较简单,用了暴力方法,竟然都通过了

t=int(input())
for i in range(t):
    nn=int(input())
    tour=[int(s) for s in input().split()]
    ans=0
    if nn==3:
        if tour[1]-tour[0]>0 and tour[1]-tour[2]>0:
            print('Case #{}: {}'.format(i+1,1))
        else:
            print('Case #{}: {}'.format(i+1,0))
    else:
        kk=1
        while kk<nn-1:
            if tour[kk]>tour[kk-1] :
                if tour[kk]>tour[kk+1]:
                    ans=ans+1
                    kk=kk+2
                elif tour[kk]==tour[kk+1]:
                    kk=kk+2
                else:
                    kk=kk+1
            else:
                if tour[kk]>=tour[kk+1]:
                    kk=kk+2
                else:
                    kk=kk+1
                
        print('Case #{}: {}'.format(i+1,int(ans)))

题目2 计算当前公交路线全部坐完的最晚时间
题目简述:
给了几个公交线路,给了可坐这些公交线路的时间,给了要求全部坐完的时间,问想最晚开始坐公交的话,哪天开始坐?可一天坐多趟公交。
示例:
3趟公交,要求day10全部完成,三趟公交的运行天数分别是3 7 2的倍数,那么最晚需第6天开始坐公交。
一开始我用的方法只能通过test1,test2会TLE。我也理解,因为我加了个笨拙的while循环,感觉while循环可以优化一下,但时间不够了。
先放我的笨拙解法

def sum_0(ccc):
    an=0
    for ll in ccc:
        if ll>=0:
            an=an+1
    return(an)
def need_adjust(ccc):
    ans=[]
    for ll in range(1,len(ccc)):
        if ccc[ll]<ccc[ll-1]:
            ans.append(ll-1)
    return(ans)
t=int(input())
for i in range(t):
    N,D=[int(s) for s in input().split()]
    xi=[int(s) for s in input().split()]
    begin=[0]*N
    begin_xi=[0]*N
    for k in range(N):
        if D%xi[k]==0:
            begin[k]=D
        else:
            begin[k]=int(D/xi[k])*xi[k]
        begin_xi[k]=int(D/xi[k])
    begin_diff=[begin[x]-begin[x-1] for x in range(1,N)]
    if sum_0(begin_diff)==N-1:
        ans=min(begin)
        print("Case #{}: {}".format(i+1, ans))
    else:
        while sum_0(begin_diff)!=N-1:
            need=need_adjust(begin)
            for yy in need:
                begin[yy]=(begin_xi[yy]-1)*xi[yy]
                begin_xi[yy]=begin_xi[yy]-1
            begin_diff=[begin[x]-begin[x-1] for x in range(1,N)]
        ans=min(begin)
        print("Case #{}: {}".format(i+1, ans))

比赛到时后,我看了下前排选手的解法,看到一个德国人的让我觉得极为精简的方法,啊自己怎么就想不到呢?
思路:因为有坐公交的顺序限制,所以先求最后一条公交线路的最晚完成时间,以此作为倒数第二条公交线路的完成limit,以此类推。

T = int(input())
for t in range(T):
    n, d = map(int, input().strip().split(' '))
    x = list(map(int, input().strip().split(' ')))
    for xi in reversed(x):
        d = d // xi * xi
    print('Case #{}: {}'.format(t + 1, d))

题目3 计算机器人经过一系列指令后所处位置

自己还没做出来,此处先放angrynerd的代码,倒是好理解。

class Point(object):

    def __init__(self, x, y, p):
        self.x = x
        self.y = y
        self.p = p

    def __add__(self, other):
        if isinstance(other, Point) and self.p == other.p:
            return Point((self.x + other.x) % self.p, (self.y + other.y) % self.p, self.p)
        else:
            return NotImplemented()

    def __mul__(self, other):
        if isinstance(other, int):
            return Point((self.x * other) % self.p, (self.y * other) % self.p, self.p)
        else:
            return NotImplemented()

p = 10**9
dir = {
    'N': Point( 0, -1, p),
    'S': Point( 0, 1, p),
    'W': Point(-1, 0, p),
    'E': Point( 1, 0, p),
}

def parse(s):
    s = iter(s)
    coord = Point(0, 0, p)
    try:
        while True:
            c = next(s)
            if c in dir:
                coord += dir[c]  # __add__
            elif c == ')':
                return coord
            else:
                assert next(s) == '('
                coord += parse(s) * int(c)  # __mul__
    except StopIteration:
        return coord

T = int(input())
for t in range(T):
    q = parse(input().strip())
    print('Case #{}: {} {}'.format(t + 1, q.x + 1, q.y + 1))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值