我得到了这个任务:
给你5个整数a,b,c,d,k。打印x+y的最大值遵循给定条件:
- a<x<b
- c<y<d
- x^y=k('^'符号表示XOR运算(
限制:
- 0<=a<=b<=10^18
- 0<=c<=d<=10^18
解释:
- x和y是2个数字
- k是它们的xor值
- [a、b]是x的范围
- [c,d]是y的范围
我的尝试:
found=False
a,b,c,d,k=map(int,input().split())
for x in range(b,a,-1):
if found==True:
break
for y in range(d,c,-1):
if x^y ==k:
print(x+y)
found=True
break
我知道这是蛮力,但这是我能想到的唯一解决问题的算法,但这显然行不通,因为时间复杂度是O((b-a(*(d-c((,或者在最坏的情况下,可能需要10^36次运算。这种方法需要优化到对数或恒定的时间复杂度。
从这里阅读类似的问题,
X+Y=(X^Y(+2*(X&Y(
所以,
ans=k+2*(X和Y(
所以,我需要找到2个给定范围的数字的最大值和运算。但是怎么做呢?
感谢您的帮助。
10^18大约是2^60(稍小(。您可以处理这些位,只检查能给出有效异或结果的数字。这已经比你的算法好很多了,但我不知道它是否足够好。
public long solve(long a, long b, long c, long d, long k) {
return solve(a, b, c, d, k, 0L, 0L, 1L << 59);
}
private long solve(long a, long b, long c, long d, long k, long x, long y, long mask) {
if (mask == 0)
return x >= a && x <= b && y >= c && y <= d ? x + y : -1L;
if ((mask & k) == 0) {
if ((mask | x) <= b && (mask | y) <= d) {
long r = solve(a, b, c, d, k, x | mask, y | mask, mask >> 1);
if (r > 0)
return r;
}
if ((mask | x) > a && (mask | y) > c)
return solve(a, b, c, d, k, x, y, mask >> 1);
} else {
if ((mask | x) > a && (mask | y) <= d) {
long r = solve(a, b, c, d, k, x, y | mask, mask >> 1);
if (r > 0)
return r;
}
if ((mask | x) <= b && (mask | y) > c)
return solve(a, b, c, d, k, x | mask, y, mask >> 1);
}
return -1L;
}
将基数为2的数字视为从大到小的位数组。
有4个不等式约束:
a<=x
在结束时满足,或者如果x
首先有一个1,其中a
有一个0x<=b
在末尾满足,或者如果x
首先具有0,其中b
具有1c<=y
在末尾满足,或者如果y
首先具有1,其中c
具有0y<=d
在结束时满足,或者如果y
首先具有0,其中d
具有0
因此,在每一位之后,我们都有一个由哪些不等式约束当前已完成或处于活动状态组成的状态。该状态可以由范围0..15
中的数字来表示。对于每个状态,我们只关心x
和y
的已设置比特的值的最大和。
这是动态编程的完美设置。
def to_bits (n):
answer = []
while 0 < n:
answer.append(n&1)
n = n >> 1
return answer
def solve (a, b, c, d, k):
a_bits = to_bits(a)
b_bits = to_bits(b)
c_bits = to_bits(c)
d_bits = to_bits(d)
k_bits = to_bits(k)
s = max(len(a_bits), len(b_bits), len(c_bits), len(d_bits), len(k_bits))
while len(a_bits) < s:
a_bits.append(0)
while len(b_bits) < s:
b_bits.append(0)
while len(c_bits) < s:
c_bits.append(0)
while len(d_bits) < s:
d_bits.append(0)
while len(k_bits) < s:
k_bits.append(0)
a_open = 1
b_open = 2
c_open = 4
d_open = 8
best_by_state = {15: 0}
for i in range(s-1, -1, -1):
next_best_by_state = {}
power = 2**i
if 0 == k_bits[i]:
choices = [(0, 0), (1, 1)]
else:
choices = [(0, 1), (1, 0)]
for state, value in best_by_state.items():
for choice in choices:
next_state = state
# Check all conditions, noting state changes.
if (state & a_open):
if choice[0] < a_bits[i]:
continue
elif a_bits[i] < choice[0]:
next_state -= a_open
if (state & b_open):
if b_bits[i] < choice[0]:
continue
elif choice[0] < b_bits[i]:
next_state -= b_open
if (state & c_open):
if choice[1] < c_bits[i]:
continue
elif c_bits[i] < choice[1]:
next_state -= c_open
if (state & d_open):
if d_bits[i] < choice[1]:
continue
elif choice[1] < d_bits[i]:
next_state -= d_open
next_value = value + power * sum(choice)
if next_best_by_state.get(next_state, -1) < next_value:
next_best_by_state[next_state] = next_value
best_by_state = next_best_by_state
possible = best_by_state.values()
if 0 < len(possible):
return max(possible)
else:
return None
打印(求解(10000000000000002000000000000000300000000000000036000000000003333000333000333(
这个程序的性能在位数上是线性的。