C. New Game题解 与 map方法 与 读入方式初学

109 阅读2分钟

题意为t组数据,每组数据给n个数字一个k,求一个最大值m,从n个数据中选择m个,使其在排序后相邻两数之差不大于一,且出现过的数不超过k个

很简单,把数字排序,利用滑动窗口获取对于每个右端点,能达到的最左左端点,两点之间即为合法序列.

实现较为简单,但请对比一下两版本代码

优化后

from queue import PriorityQueue
from collections import defaultdict
t = int(input())

def solve():
    n, k = map(int, input().split())
    e = list(map(int, input().split()))
    e.sort()
    mp = defaultdict(int)
    ans, el, cnt = 0,0,0
    for er in range(n):
        if er > 0 and e[er] - e[er - 1] > 1:
            el = er
            cnt = 0
        if mp[e[er]] == 0:
            cnt += 1
        mp[e[er]] += 1
        while cnt > k:
            mp[e[el]] -= 1
            if mp[e[el]] == 0:
                cnt -= 1
            el += 1
        ans = max(ans, er - el + 1)
    return ans

while t > 0:
    t -= 1
    print(solve())

优化前

from queue import PriorityQueue
from collections import defaultdict
t = int(input())

def solve():
    n,k = [eval(item) for item in input().split(' ')]
    e = [eval(item) for item in input().split(' ')]
    e.sort()
    cnt = 0
    mp = defaultdict(int)
    el = 0
    ans = 0
    for er in range(n):
        if er > 0 and e[er] - e[er - 1] > 1:
            while el < er:
                mp[e[el]] -= 1
                el += 1
            cnt = 0
        if mp[e[er]] == 0:
            cnt += 1
        mp[e[er]] += 1
        while cnt > k:
            mp[e[el]] -= 1
            if mp[e[el]] == 0:
                cnt -= 1
            el += 1
        ans = max(ans, er - el + 1)
    return ans

while t > 0:
    t -= 1
    print(solve())

抛开无关复杂度不谈,让我们注意两个读取方式

n, k = map(int, input().split())
e = list(map(int, input().split()))
n,k = [eval(item) for item in input().split(' ')]
e = [eval(item) for item in input().split(' ')]

根据测试,后者处理速度至少为前者五倍 前者405ms解决 后者2000ms tle

是什么

可以进行一个简单的map的模拟

def my_map(func, *iterables):
    
    iterators = [iter(it) for it in iterables]
    while True:
        try:
            args = [next(it) for it in iterators]
            yield func(*args)
        except StopIteration:
            break

def square(x):
    return x * x

numbers = [1,2,3,4,5]
squared_number = my_map(square, numbers)

print(list(squared_number))

1.*iterables

解包(unpacking)操作语法,将一个刻碟带对象的元素解包成单独的参数.

函数调用时使用

def my_function(a, b, c):
    print(a, b, c)

my_list = [1, 2, 3]
my_function(*my_list)

将传入的列表转化三个单独的位置参数传递给'mu_function'

函数定义时使用

def my_function(*args):
    print(args)

my_function(1, 2, 3)  # 输出: (1, 2, 3)

必须是最后一个位置参数,会捕获所有剩余的位置参数.

2.next

未完待续