![](/img/trans.png)
[英]Find if a number is a possible sum of two or more numbers in a given set - python
[英]Given xor and the range of 2 numbers, find their maximum possible sum
我得到了這個任務:
給你 5 個整數 a,b,c,d,k。 打印滿足給定條件的 x+y 的最大值:
- a<=x<=b
- c<=y<=d
- x^y=k('^'符號表示異或運算)
約束:
- 0 <= a <= b <= 10^18
- 0 <= c <= d <= 10^18
解釋:
我的嘗試:
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((ba)*(dc)) 或者在最壞的情況下,它可以進行 10^36 次操作。 這種方法需要優化為對數或恆定時間復雜度。
從這里閱讀類似的問題,
X+Y = (X ^ Y) + 2 * (X & Y)
所以,
答案 = 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 中的數字視為 arrays 位,從最大到最小。
有 4 個不等式約束:
a<=x
最后滿足,或者如果x
首先是 1,而a
是 0。x<=b
最后滿足,或者如果x
首先是 0,而b
是 1。c<=y
最后滿足,或者如果y
首先是 1,而c
是 0。y<=d
最后滿足,或者如果y
首先是 0,而d
是 0。 因此,在每個位之后,我們都有一個 state ,其中包含當前已完成或處於活動狀態的不等式約束。 這個 state 可以用0..15
范圍內的數字表示。 對於每個 state,我們只關心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
打印(解決(10000000000000000,2000000000000000,3000000000000000,3600000000000000,3333000333000333))
該程序的性能與位數成線性關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.