簡體   English   中英

給定 xor 和 2 個數字的范圍,找到它們的最大可能和

[英]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

解釋:

  • x 和 y 是 2 個數字,
  • k 是它們的異或值,
  • [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((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 個不等式約束:

  1. a<=x最后滿足,或者如果x首先是 1,而a是 0。
  2. x<=b最后滿足,或者如果x首先是 0,而b是 1。
  3. c<=y最后滿足,或者如果y首先是 1,而c是 0。
  4. y<=d最后滿足,或者如果y首先是 0,而d是 0。

因此,在每個位之后,我們都有一個 state ,其中包含當前已完成或處於活動狀態的不等式約束。 這個 state 可以用0..15范圍內的數字表示。 對於每個 state,我們只關心xy已設置位的值的最大總和。

這是動態編程的完美設置。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM