对于SPOJ上的问题,我的问题是“超出时间限制”错误。因为我认为这个错误是因为输入很大,所以我需要你的帮助来找到处理大输入的最佳方法。
让我解释输入和我的代码。
输入
输入的第一行包含测试用例t(1 <= t <= 100)。它是 然后是2 * t行,每个测试用例2行。第一行输入 对于每个测试用例,包含数n(0 <= n <= 10 ^ 6),然后是n 下一行中的元素。每个数字从-10 ^ 3到+ 10 ^ 3
以下是输入
的示例3 #number of test cases (t)
4 #number of elements that will come to next line (n) (this can be 10^6)
2 1 2 2 #this line may have 10^6 numbers
6
1 1 1 2 2 2
5
1 2 4 5 1
问题是询问一个数字是否超过n // 2次。 示例输出
YES 2 #because 2 appears 3 times.
NO # no number occurs more than n//2 times
NO # no number occurs more than n//2 times.
有关此问题的更多信息
添加者:Troika ::字节日期:2010-02-18时间限制:1s来源 限制:50000B内存限制:256MB集群:金字塔(Intel Pentium III 733 MHz)语言:除了以下所有内容:PERL 6
http://www.spoj.com/problems/MAJOR/
最后我的代码。
from collections import Counter
import re
def major(n):
s = input().split() # get all the numbers one by one
y = (Counter(s)).most_common()[0] # Count how many times a number occurs in the input and return the most occurence with its value in a pair.
if y[1]> n//2: #if the most occurence is more than half of the "n"
return "YES " + y[0] # return the value belongs to the most occurence
else:
return "NO"
for i in range(int(input())): #get the number of test cases
print(major(int(input()))) # calling the function to get the "n"
我想知道s = re.findall(r'\d+', input())
是否对于像一百万的数字来说速度太慢,我已将输入部分更改为s = input().split()
。但是,我再次收到“时间限制超出“错误。它可能与Counter
函数有关吗?
答案 0 :(得分:2)
您可以通过以下方式对其进行优化:
禁用垃圾回收:
import gc
gc.disable()
避免string.split
并使用re.finditer
。
避免使用range
并使用while循环。
使用sys.stdin.readline()
代替input
(速度更快)和sys.stdout.write
打印内容。
当数字的出现次数大于n // 2
时停止(同样,仅计算一次)。您可以使用collections.defaultdict
并在更新前检查事件。
避免使用这些功能,只需将所有内容放在一个循环中。
有时在main
函数中导入库可以节省时间。
不幸的是,Martijn Pieters指出,Python 3.x没有可接受的解决方案,Python 2.x只有一个解决方案,并且根据解决它的内存量,numerix可能已经使用{ {1}}(PyPy所基于的库,比CPython快得多)。不幸的是,由于psyco
已经停止,它的支持已被删除在集群上,问题被执行,因此可能没有人会设法发送已接受的解决方案,直到他们重新启用psyco
或PyPy支持。
psyco
修改强>
我发送了一封电子邮件给 numerix ,他确认他的解决方案使用了import gc
gc.disable()
# import psyco
# psyco.full()
def main():
from collections import defaultdict
from sys import stdin, stdout
import re
pattern = re.compile(r'\d+')
times = int(stdin.readline())
while times:
times -= 1
threshold = int(stdin.readline()) // 2
vals = defaultdict(int)
for x in pattern.finditer(stdin.readline()):
n = int(x.group(0))
rep = vals[n] + 1
if rep > threshold:
stdout.write('YES ' + str(n) + '\n')
break
else:
vals[n] = rep
else:
stdout.write('NO\n')
if __name__ == '__main__':
main()
:
是的,我的MAJOR解决方案使用psyco。我没有尝试没有psyco,但由于没有其他的AC Python解决方案,我想它不可能或只有重度i / o优化。