问题
给你一套S = {1,2,3...N}
。从集合中找到两个整数:cc和A
,这样最大值可能小于给定的整数。在这种情况下,B
按位表示运算符and。
2 <= N <= 10^3
2 <= K <= N
解决方案
#Brute force
testCases = int(raw_input())
while testCases > 0:
n_k = raw_input().split()
n = range(1, int(n_k[0]) + 1) #THIS IS THE RANGE S
k = int(n_k[1])
max_pair = -1
for x in n[:len(n)-1]:
for y in n[x:]:
x_y = x & y
if( x_y < k):
max_pair = max(max_pair, x_y)
print max_pair
testCases -= 1
问题
我已经讨论了如何改进这段代码,但还没有得到答案。当n很长时,我得到一个超时错误。有人能给我指出正确的方向来找出如何改进这段代码吗?我想不出缩短循环的方法,我可以使用什么标准?按位&会让你丢失信息,这并不是说有一种可逆的方法(比如当你加上时,要把它拿回,你就要减去…)。
我的思路:
(A&B)我从第一个循环中知道A,如何使第二个循环的迭代次数更少?
(A&B)=1…(k-1)
在这个世界上,我怎样才能把b移到方程的另一边,以便在第二个循环中更快地开始丢弃数字呢?
编辑:解决方案
我肯定在笑这个。多亏了用户@ead,我了解到python有一个更快的解释器,所以我没有选择“python 2”,而是选择了“pypypy2”…所有测试用例都以惊人的速度通过,并且没有超时错误我已经热血沸腾了好几天…真不敢相信,哈哈哈。
对于lols,我继续把代码翻译成使用js(node.js)和low,然后看到…不是超时错误。如果有人想要js中的代码,就在这里。
function processData(input) {
var data = input.split("\n");
var testCases = parseInt(data[0]);
var n_k, n, k, max_pair;
for(let index=1; index<data.length; ++index){
n_k = data[index].split(" ");
n = getSet( parseInt(n_k[0]) ),
k = parseInt(n_k[1]);
max_pair = 0;
n.forEach(function(a){
for(let i=a; i<n.length; ++i){
let a_b = a & n[i];
if(a_b < k)
max_pair = Math.max(max_pair, a_b);
}
});
console.log(max_pair);
}
}
function getSet(n){
var n_set = [];
for(let index=1; index<=n; ++index)
n_set.push(index);
return n_set;
}
最佳答案
我认为没有什么特别的,只是CPython对于整数运算来说非常慢用C/C++编写,程序非常快,不需要超过0.01秒。
在相互竞争的编程中,很多问题都不是用cpython来解决的,而是用PyPy来解决,它有更快的整数运算和git编译器,而python解释器和cpython一样。
所以只要有可能就在比赛中选择皮比。
关于algorithm - 提高性能(超时错误),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45489696/