HackerRank" AND product"

时间:2016-03-02 10:19:06

标签: python bit-manipulation bitwise-operators

当我在HackerRank挑战" AND产品" ...

中提交以下测试用例代码时
  

您将获得两个整数A和B.您需要计算位于A和B之间的所有自然数中的按位AND。

     

输入格式:   输入的第一行包含T,即要遵循的测试用例的数量。   换行符中的每个测试用例包含由单个空格分隔的A和B.

from math import log
for case in range(int(raw_input())):
    l, u = map(int, (raw_input()).split())
    if log(l, 2) == log(u, 2) or int(log(l,2))!=int(log(l,2)):
        print 0
    else:
        s = ""
        l, u = [x for x in str(bin(l))[2:]], [x for x in str(bin(u))[2:]]
        while len(u)!=len(l):
            u.pop(0)
        Ll = len(l)
        for n in range(0, len(l)):
            if u[n]==l[n]:
                s+=u[n]
        while len(s)!=len(l):
            s+="0"
        print int(s, 2)

...它通过了9个测试用例,显示了"运行时错误"在1个测试案例和节目"错误答案"其余10个。

这有什么不对?

2 个答案:

答案 0 :(得分:0)

最好使用python的Bitwise运算符。对于AND它是 - '&'

取a,b = input()。strip()。split('') a,b = [int(a),int(b)] 然后设置一个循环,检查a和b之间的所有值

J = A + 1

X = A

而(J< = B):

x = x&j

j+=1

打印(x)的

有关Bitwise运算符的更多信息,您可以看到:https://wiki.python.org/moin/BitwiseOperators

答案 1 :(得分:-1)

是的,你可以更快地做到这一点。 你这样做非常简单,计算for循环中的所有ands。

实际上应该可以在O(1)(我认为)

中计算出来

但这里有一些优化:

1)如果你得到的值 0 ,就会中止for循环,因为无论什么

它都会 0

2)如果lu return 0之间存在 2 的强度(在这种情况下你不需要循环)

我对O(1)的想法是考虑哪些位在ul之间发生变化。

因为答案中ul之间的某个位置变为 0

编辑1:以下是O(same leading digits)时间的答案。

https://math.stackexchange.com/questions/1073532/how-to-find-bitwise-and-of-all-numbers-for-a-given-range

编辑2:这是我的代码,我没有广泛测试它,但它似乎工作。 (O(日志(n))的

from math import log

for case in [[i+1,j+i+1] for i in range(30) for j in range(30)]:
    #Get input
    l, u = case


    invL=2**int(log(l,2)+1)-l
    invU=2**int(log(u,2)+1)-u


    #Calculate pseudo bitwise xnor of input and format to binary rep
    e=format((u&l | invL & invU),'010b')
    lBin=format(l,'010b')
    #output to zero
    res=0

    #boolean to check if we have found any zero
    anyZero=False

    #boolean to check the first one because we have leading zeros
    firstOne=False

    for ind,i in enumerate(e):
        #for every digit

        #if it is a leading one
        if i=='1' and (not anyZero):
            firstOne=True
            #leftshift result (multiply by 2)
            res=res<<1
            #and add 1
            res=res+int(lBin[ind])
        #else if we already had a one and find a zero this happens every time
        elif(firstOne):
            anyZero=True
            #leftshift
            res=res<<1
    #test if we are in the same power, if not there was a power between

    if(res!=0):
        #print "test",(int(log(res,2))!=int(log(l,2))) | ((log(res,2))!=int(log(u,2)))
        if((int(log(res,2))!=int(log(l,2))) or (int(log(res,2))!=int(log(u,2)))):
            res=0

    print res

enter image description here

为每一个测试用例而工作。获得最后一个所需的微小变化。你必须找出自己的小变化。严重