【问题标题】:Python list sort and simulation optimization problemPython列表排序与仿真优化问题
【发布时间】:2021-09-25 18:56:47
【问题描述】:

我再次尝试解决一个问题来为即将到来的 USACO 比赛练习,但无法满足 1 秒的时间限制:https://open.kattis.com/contests/v4xrif/problems/knigsoftheforest

所有的驼鹿都是森林之王,但你最近的驼鹿朋友, Karl-Älgtav,比大多数人更有趣。部分原因是他 对发酵蓝莓的喜爱,部分原因是他的部落 住在里面。每年他的部落都会举办一场比赛来确定 年的阿尔法驼鹿。获胜者可以领导部落一年,并且 然后永久离开部落。竞争者池保持不变 多年来保持不变,除了旧的 alpha-moose 被替换 每场比赛的新人。

Karl-Älgtav 最近开始想知道什么时候会轮到他 赢了,并要求你帮助他确定这一点。他提供了一个 他部落中每只其他驼鹿的力量列表 在接下来的 n-1 年内竞争,以及他们进入的时间 比赛。假设每年的获胜者是驼鹿 最强大的力量,确定 Karl-Älgtav 何时成为阿尔法驼鹿。

输入第一行输入包含两个空格分隔的整数k(1≤k≤100000)和n(1≤n≤100000),表示输入的大小 锦标赛池和您参加的年数 提供了足够的信息。

接下来是描述 Karl-Älgtav 的单行,包含两个 整数 y (2011≤y≤2011+n−1) 和 p (0≤p≤2^31−1)。这是他的一年 分别是参加比赛和他的实力。

然后按照 n+k-2 行描述其他驼鹿,在 与 Karl-Älgtav 的格式相同。

请注意,恰好 k 个驼鹿将 2011 年作为它们的年份 进入,剩下的 n-1 只驼鹿将有独特的年份 进入。

您可以假设每只驼鹿的力量都是独一无二的。

输出 Karl-Älgtav 赢得比赛的年份,或者如果给定的数据不足以确定这一点,则未知。

示例输入 1

2 4
2013 2
2011 1
2011 3
2014 4
2012 6

样本输出 1

2013

示例输入 2

2 4
2011 1
2013 2
2012 4
2011 5
2014 3

样本输出 2

unknown

我的逻辑: 得到所有的驼鹿,并按强度分类。然后从那里逐年模拟,从所有驼鹿名单中删除每年的获胜者,如果 Karl-Älgtav 是获胜者,则打破循环。如果循环完成并且我们还没有爆发,我们不知道他什么时候会赢,所以我们打印'unknown'

我的代码:

line = input().strip().split()
k, n = int(line[0]), int(line[1])
line = input().strip().split()
m = (int(line[0]), int(line[1]))
c = [None for i in range(n+k-1)]
for i in range(n+k-2):
    line = input().strip().split()
    c[i] = ((int(line[0]), int(line[1])))
c[-1] = m
c.sort(key = lambda i:i[1])

year = 2011
won = False
for i in range(n):
    yc = [y for y in c if y[0] <= year]
    w = yc[-1]
    c.remove(w)
    if w == m:
        print(year)
        won = True
        break
    year += 1
    
if not won:
    print('unknown')

我正在尝试加快速度,但失败了。其他人能弄清楚吗?我最近还注意到,对于大多数有竞争力的编程问题,如果你不能在 Python 中强制它,你可以在 Java 或 C++ 中。对于竞争性编程,是否建议我花更多时间学习这些语言或学习如何更好地优化 Python?

我尝试了使用字典和堆的不同方法,但仍然没有达到时间限制。不过,它还有一个测试用例

代码:

from heapq import heappop, heappush, heapify

line = input().strip().split()
K, N = int(line[0]), int(line[1])
line = input().strip().split()
karl = (int(line[0]), int(line[1]))
moosen = {karl[1] : karl[0]}
for i in range(N+K-2):
    line = input().strip().split()
    moosen[int(line[1])] = (int(line[0]))

heap = []
heapify(heap)
won = False
for year in range(2011, 2011 + N):
    mc = moosen.copy()
    for k,v in moosen.items():
        if v <= year:
            heappush(heap, -k)
            mc.pop(k)
    moosen = mc.copy()

    if -heappop(heap) == karl[1]:
        won = True
        print(year)
        break

if not won:
    print('unknown')

【问题讨论】:

  • 为什么要事先对所有驼鹿进行分类?锦标赛规模可以小得多 - 您只需每年移除锦标赛的顶级成员(您可以使用堆获取)。
  • @CaptainTrojan 我不明白你的意思......你能详细说明一下吗?
  • 你认为为什么需要按强度对所有驼鹿进行分类?
  • @CaptainTrojan 因此,当我创建子列表 yc 时,我不必对其进行排序,我可以将最后一个值作为获胜者
  • 它还告诉您某些值您可以认为是唯一的,这意味着您可以使用一个集合...这可能会提高性能。

标签: python arrays list optimization simulation


【解决方案1】:

所以基本上我修改了我的第二种方法(见问题),以便键和值颠倒,这使得字典搜索更快! 代码:

from heapq import heappop, heappush, heapify
from collections import defaultdict

line = input().strip().split()
K, N = int(line[0]), int(line[1])
line = input().strip().split()
karl = (int(line[0]), int(line[1]))
moosen = defaultdict(list)
for i in range(N+K-2):
    line = input().strip().split()
    moosen[int(line[0])].append(int(line[1]))
moosen[karl[0]].append(karl[1])
heap = []
heapify(heap)
won = False
for year in range(2011, 2011 + N):
    for i in moosen[year]:
        heappush(heap, -i)
    if -heappop(heap) == karl[1]:
        won = True
        print(year)
        break

if not won:
    print('unknown')

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2012-10-20
    • 1970-01-01
    • 2012-04-30
    • 2011-11-26
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多