Java 如何使程序更快[键盘\u粘滞\u注释] 键盘便签
仆从们把布尔教授的一些秘密安全地锁起来了。或者他们是这么想的。事实上,他们非常自信,他们甚至在锁的键盘上贴了一张密码提示的便条 锁要求您在键盘中输入一对非负整数(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 输出: (内部)1Java 如何使程序更快[键盘\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(其中^是按位异或运算)
公共静态整数应答(整数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)