题意为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
未完待续