Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使程序更快[键盘\u粘滞\u注释] 键盘便签_Java_Algorithm_Challenge Response - Fatal编程技术网

Java 如何使程序更快[键盘\u粘滞\u注释] 键盘便签

Java 如何使程序更快[键盘\u粘滞\u注释] 键盘便签,java,algorithm,challenge-response,Java,Algorithm,Challenge Response,仆从们把布尔教授的一些秘密安全地锁起来了。或者他们是这么想的。事实上,他们非常自信,他们甚至在锁的键盘上贴了一张密码提示的便条 锁要求您在键盘中输入一对非负整数(a,b)。由于整数可能高达20亿,您可以从便笺中寻求帮助 便条上写着两个数字,但即使是仆从也知道足够多的信息,不会把密码放在上面。他们实际上写下了密码整数对(a,b)的和(标记为s)和按位异或(xor,标记为x)。这样,他们只需要记住一个。如果减法有困难,可以使用位异或 i、 例如,我们有s=a+b和x=a^b(其中^是按位异或运算)

仆从们把布尔教授的一些秘密安全地锁起来了。或者他们是这么想的。事实上,他们非常自信,他们甚至在锁的键盘上贴了一张密码提示的便条

锁要求您在键盘中输入一对非负整数(a,b)。由于整数可能高达20亿,您可以从便笺中寻求帮助

便条上写着两个数字,但即使是仆从也知道足够多的信息,不会把密码放在上面。他们实际上写下了密码整数对(a,b)的和(标记为s)和按位异或(xor,标记为x)。这样,他们只需要记住一个。如果减法有困难,可以使用位异或

i、 例如,我们有s=a+b和x=a^b(其中^是按位异或运算)

使用自动黑客设备,每次尝试输入猜测都需要几毫秒。因为在你被发现之前你只有一点时间,你想知道在你能够尝试所有的组合之前可能需要多长时间。多亏了这张便条,你现在可以消除某些组合,甚至不必将它们输入键盘,你还可以确切地知道破解锁需要多长时间——在最坏的情况下

编写一个名为answer(s,x)的函数,该函数用于查找具有目标sum和xor的对数(a,b)

例如,如果s=10且x=4,则(a,b)的可能值为(3,7)和(7,3), 所以答案是2

如果s=5和x=3,则不存在可能的值,所以答案将返回0

s和x至少为0,最多为20亿

语言文字 要提供Python解决方案,请编辑solution.py 要提供Java解决方案,请编辑solution.Java

测试用例 投入: (int)s=10 (int)x=4 输出: (内部)2

投入: (int)s=0 (int)x=0 输出: (内部)1

公共静态整数应答(整数s,整数x){
List num=new ArrayList();
INTA;
int b;
整数和;
国际金融机构;

对于(inti=0;i尝试将num更改为HashSet。最后还可以清理if/else

e、 g

公共静态整数应答(整数s,整数x){
HashSet num=新的HashSet();
INTA;
int b;
整数和;
国际金融机构;

对于(int i=0;i算法中的大多数步骤执行的工作太多:

  • 对所有小于或等于
    s
    的非负整数进行线性扫描。由于问题是对称的,因此扫描小于或等于
    s/2
    就足够了
  • 您进行第二次线性扫描,为每个
    a
    找到另一个满足
    a+b=s
    要求的整数
    b
    。简单的代数表明只有一个这样的
    b
    ,即
    s-a
    ,因此根本不需要线性扫描
  • 您进行第三次线性扫描以检查是否已找到一对
    (a,b)
    。如果仅循环到
    s/2
    ,它将始终保持
    a≤b
    ,因此您不会遭受重复计数
最后,我可以想出一个简单的优化来节省一些工作:

  • 如果
    s
    是偶数,那么
    a
    b
    都是偶数,或者都是奇数。因此,在这种情况下,
    a^b
    是偶数
  • 如果
    s
    为奇数,则
    a
    b
    为奇数,因此
    a^b
    为奇数
您可以在执行任何工作之前添加该检查:

public static int answer(int s, int x) {
    int result = 0;
    if (s % 2 == x % 2) {
        for (int a = 0; a <= s / 2; a++) {
            int b = s - a;
            if ((a ^ b) == x) {
                result += 2;
            }
        }
        // we might have double counted the pair (s/2, s/2)
        // decrement the count if needed
        if (s % 2 == 0 && ((s / 2) ^ (s / 2)) == x) {
            result--;
        }
    }
    return result;
}
公共静态整数应答(整数s,整数x){
int结果=0;
如果(s%2==x%2){

对于(int a=0;a您可以通过了解传入状态(异或数字、总和数字、传入进位)的传出状态(传出进位)数量有限来解决此问题。您可以使用
if
条件来处理每个状态,并使用递归来计算组合的总数。您可以使用记忆来提高递归的效率。下面我的解决方案解决了
O(m)中的问题
time,其中
m
是数字数据类型中的二进制位数。由于问题指定
m=32
(整数),从技术上讲,这是一个
O(1)
解决方案

如果您有任何问题,请告诉我。我尝试在代码中添加有用的注释来解释各种情况

public class SumAndXor {
    public static void main(String[] args) {
        int a = 3;
        int b = 7;

        int sum = a + b;
        int xor = a ^ b;

        System.out.println(answer(sum, xor));
    }

    private static final int NOT_SET = -1;

    // Driver
    public static int answer(int sum, int xor) {
        int numBitsPerInt = Integer.toBinaryString(Integer.MAX_VALUE).length() + 1;
        int[][] cache = new int[numBitsPerInt][2];

        for (int i = 0; i < numBitsPerInt; ++i) {
            cache[i][0] = NOT_SET;
            cache[i][1] = NOT_SET;
        }

        return answer(sum, xor, 0, 0, cache);
    }

    // Recursive helper
    public static int answer(int sum, int xor, int carry, int index, int[][] cache) {
        // Return memoized value if available
        if (cache[index][carry] != NOT_SET) {
            return cache[index][carry];
        }

        // Base case: nothing else to process
        if ((sum >> index) == 0 && (xor >> index) == 0 && carry == 0) {
            return 1;
        }

        // Get least significant bits
        int sumLSB = (sum >> index) & 1;
        int xorLSB = (xor >> index) & 1;

        // Recursion
        int result = 0;

        if (carry == 0) {
            if (xorLSB == 0 && sumLSB == 0) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 0 and the incoming carry is 0, both [0, 0] and [1, 1] are valid. We
                // recurse with a carry of 0 to represent [0, 0], and we recurse with a carry of
                // 1 to represent [1, 1].
                result = answer(sum, xor, 0, index + 1, cache) + answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 0 && sumLSB == 1) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 1 and the incoming carry is 0, neither [0, 0] nor [1, 1] is valid.
                result = 0;
            } else if (xorLSB == 1 && sumLSB == 0) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 0 and the incoming carry is 0, neither [0, 1] nor [1, 0] is valid.
                result = 0;
            } else if (xorLSB == 1 && sumLSB == 1) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 1 and the incoming carry is 0, both [0, 1] and [1, 0] is valid. We
                // recurse with a carry of 0 to represent [0, 1], and we recurse with a carry
                // of 0 to represent [1, 0].
                result = 2 * answer(sum, xor, 0, index + 1, cache);
            }
        } else {
            if (xorLSB == 0 && sumLSB == 0) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 0 and the incoming carry is 1, neither [0, 0] nor [1, 1] is valid.
                result = 0;
            } else if (xorLSB == 0 && sumLSB == 1) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 1 and the incoming carry is 1, both [0, 0] and [1, 1] are valid. We
                // recurse with a carry of 0 to represent [0, 0], and we recurse with a carry of
                // 1 to represent [1, 1].
                result = answer(sum, xor, 0, index + 1, cache) + answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 1 && sumLSB == 0) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 0 and the incoming carry is 1, both [0, 1] and [1, 0] are valid. We
                // recurse with a carry of 0 to represent [0, 1], and we recurse with a carry
                // of 0 to represent [1, 0].
                result = 2 * answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 1 && sumLSB == 1) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 1 and the incoming carry is 1, neither [0, 1] nor [1, 0] is valid.
                result = 0;
            }
        }

        cache[index][carry] = result;

        return result;
    }
}
公共类SumAndXor{
公共静态void main(字符串[]args){
INTA=3;
int b=7;
整数和=a+b;
int xor=a^b;
System.out.println(answer(sum,xor));
}
私有静态final int NOT_SET=-1;
//司机
公共静态整数应答(整数和,整数异或){
int numBitsPerInt=Integer.toBinaryString(Integer.MAX_值).length()+1;
int[]cache=newint[numBitsPerInt][2];
对于(int i=0;i>索引)==0&&(异或>>索引)==0&&进位==0){
返回1;
}
//获取最低有效位
int sumLSB=(总和>>索引)&1;
int xorLSB=(xor>>索引)&1;
//递归
int结果=0;
如果(进位==0){
if(xorLSB==0&&sumLSB==0){
//由于XOR为0,因此二进制数字为[0,0]或[1,1]
//求和为0,进位为0,[0,0]和[1,1]都有效。我们
//使用进位0递归以表示[0,0]和w
public static int answer(int s, int x) {
    int result = 0;
    if (s % 2 == x % 2) {
        for (int a = 0; a <= s / 2; a++) {
            int b = s - a;
            if ((a ^ b) == x) {
                result += 2;
            }
        }
        // we might have double counted the pair (s/2, s/2)
        // decrement the count if needed
        if (s % 2 == 0 && ((s / 2) ^ (s / 2)) == x) {
            result--;
        }
    }
    return result;
}
public class SumAndXor {
    public static void main(String[] args) {
        int a = 3;
        int b = 7;

        int sum = a + b;
        int xor = a ^ b;

        System.out.println(answer(sum, xor));
    }

    private static final int NOT_SET = -1;

    // Driver
    public static int answer(int sum, int xor) {
        int numBitsPerInt = Integer.toBinaryString(Integer.MAX_VALUE).length() + 1;
        int[][] cache = new int[numBitsPerInt][2];

        for (int i = 0; i < numBitsPerInt; ++i) {
            cache[i][0] = NOT_SET;
            cache[i][1] = NOT_SET;
        }

        return answer(sum, xor, 0, 0, cache);
    }

    // Recursive helper
    public static int answer(int sum, int xor, int carry, int index, int[][] cache) {
        // Return memoized value if available
        if (cache[index][carry] != NOT_SET) {
            return cache[index][carry];
        }

        // Base case: nothing else to process
        if ((sum >> index) == 0 && (xor >> index) == 0 && carry == 0) {
            return 1;
        }

        // Get least significant bits
        int sumLSB = (sum >> index) & 1;
        int xorLSB = (xor >> index) & 1;

        // Recursion
        int result = 0;

        if (carry == 0) {
            if (xorLSB == 0 && sumLSB == 0) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 0 and the incoming carry is 0, both [0, 0] and [1, 1] are valid. We
                // recurse with a carry of 0 to represent [0, 0], and we recurse with a carry of
                // 1 to represent [1, 1].
                result = answer(sum, xor, 0, index + 1, cache) + answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 0 && sumLSB == 1) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 1 and the incoming carry is 0, neither [0, 0] nor [1, 1] is valid.
                result = 0;
            } else if (xorLSB == 1 && sumLSB == 0) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 0 and the incoming carry is 0, neither [0, 1] nor [1, 0] is valid.
                result = 0;
            } else if (xorLSB == 1 && sumLSB == 1) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 1 and the incoming carry is 0, both [0, 1] and [1, 0] is valid. We
                // recurse with a carry of 0 to represent [0, 1], and we recurse with a carry
                // of 0 to represent [1, 0].
                result = 2 * answer(sum, xor, 0, index + 1, cache);
            }
        } else {
            if (xorLSB == 0 && sumLSB == 0) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 0 and the incoming carry is 1, neither [0, 0] nor [1, 1] is valid.
                result = 0;
            } else if (xorLSB == 0 && sumLSB == 1) {
                // Since the XOR is 0, the binary digits are either [0, 0] or [1, 1]. Since the
                // sum is 1 and the incoming carry is 1, both [0, 0] and [1, 1] are valid. We
                // recurse with a carry of 0 to represent [0, 0], and we recurse with a carry of
                // 1 to represent [1, 1].
                result = answer(sum, xor, 0, index + 1, cache) + answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 1 && sumLSB == 0) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 0 and the incoming carry is 1, both [0, 1] and [1, 0] are valid. We
                // recurse with a carry of 0 to represent [0, 1], and we recurse with a carry
                // of 0 to represent [1, 0].
                result = 2 * answer(sum, xor, 1, index + 1, cache);
            } else if (xorLSB == 1 && sumLSB == 1) {
                // Since the XOR is 1, the binary digits are either [0, 1] or [1, 0]. Since the
                // sum is 1 and the incoming carry is 1, neither [0, 1] nor [1, 0] is valid.
                result = 0;
            }
        }

        cache[index][carry] = result;

        return result;
    }
}
def final(x, t):
    if x > 0:
        if x % 2: # x is odd
            return final(x / 2, t * 2)
        else: # x is even
            return final(x / 2, t)
    else:
        return t

def mid(l, r):
    return (l + r) / 2

def sierpinski_traverse(s_mod_xms, x. lo, hi, e, l, r):
    # you can do this in 16 lines of code to end with...
    if intersect:
        # always start with a t-value of 1 when first calling final in case x=0
        return final(x, 1)
    else:
        return 0

def answer(s, x):
    print final(x, 1)

    if s < 0 or x < 0 or s > 2000000000 or x > 2000000000 or s < x or s % 2 != x % 2:
        return 0
    if x == 0:
        return 1

    x_modulus_size = 2 ** int(math.log(x, 2) + 2)
    s_mod_xms = s % x_modulus_size
    lo_root = x_modulus_size / 4
    hi_root = x_modulus_size / 2
    exp = x_modulus_size / 4    # exponent of 2 (e.g. 2 ** exp)

    return sierpinski_traverse(s_mod_xms, x, lo_root, hi_root, exp, exp, 2 * exp)


if __name__ == '__main__':
    answer(10, 4)