📜  确定不一致的加权对象

📅  最后修改于: 2021-05-06 20:16:52             🧑  作者: Mango

给定从1到N编号的N个对象,除了只有一个事先未知的对象外,所有对象的权重都相同。我们还得到了Q比较,在每个比较中,相等数量的对象放在天平的两侧,并且被告知较重的一侧。

任务是找到不一致的加权对象或确定数据是否不足。

例子

Input : N = 6
Q = 3
1 2 = 5 6
1 2 3 > 4 5 6
3 4 < 5 6
Output : 4
Explanation: Object 4 is lighter than all other objects.

Input : N = 10
Q = 4
1 2 3 4 < 7 8 9 10
1 = 9
2 3 4 > 1 5 10
6 = 2
Output : Insufficient data

据说除了一个元素外,其余元素的权重都相同。因此,如果我们仔细观察,可以说:

  1. 在“ =”比较中,两边的对象都不是权重不一致的对象。
  2. 如果在一个比较中一个对象出现在较重的一侧,而在另一个比较中出现在较轻的一侧,则它不是加权一致的对象。这是因为,如果物体出现在较重的一侧,则重量最大;如果物体出现在较轻的一侧,则重量最小。由于单个元素不能同时为最大值和最小值。因此,这种情况将永远不会发生。
  3. 不一致加权的对象必须出现在所有非平衡(’>’或'<‘)比较中。

我们可以使用以上三个观察来缩小不一致加权对象的潜在候选对象。我们只考虑那些较重或较轻的物体。如果只有一个这样的对象,那么它就是必需的对象。如果没有这样的对象,那么我们将考虑所有没有出现在比较中的对象。如果只有一个这样的对象,那么它就是不一致加权的对象。如果没有出现这些情况,则数据不足。

下面是上述方法的实现:

# Python program to determine the 
# inconsistently weighted object 
  
# Function to get the difference of two lists 
def subt(A, B): 
    return list(set(A) - set(B)) 
  
# Function to get the intersection of two lists 
def intersection(A, B): 
    return list(set(A).intersection(set(B))) 
  
# Function to get the intersection of two lists 
def union(A, B): 
    return list(set(A).union(set(B))) 
  
# Function to find the inconsistently weighted object 
def inconsistentlyWeightedObject(N, Q, comparisons): 
    # Objects which appear on the heavier side 
    heavierObj = [i for i in range(1, N + 1)] 
      
    # Objects which appear on the lighter side 
    lighterObj = [i for i in range(1, N + 1)] 
    equalObj = [] # Objects which appear in '=' comparisons 
      
    # Objects which don't appear in any comparison 
    objectNotCompared = [i for i in range(1, N + 1)] 
      
    for c in comparisons: 
        objectNotCompared = subt(objectNotCompared, union(c[0], c[2])) 
          
        if c[1] == '=': 
            equalObj = union(equalObj, union(c[0], c[2])) 
        elif c[1] == '<': 
            # Removing those objects which do 
            # not appear on the lighter side 
            lighterObj = intersection(lighterObj, c[0]) 
              
            # Removing thoe objects which do 
            # not appear on the heavier side 
            heavierObj = intersection(heavierObj, c[2]) 
        else: 
            # Removing those objects which do 
            # not appear on the lighter side 
            lighterObj = intersection(lighterObj, c[2]) 
              
            # Removing those objects which do 
            # not appear on the heavier side 
            heavierObj = intersection(heavierObj, c[0]) 
      
    L_iwo = subt(union(heavierObj, lighterObj), equalObj) # Potential candidates 
  
    if len(L_iwo) == 1: 
        return L_iwo[0] 
    elif not len(L_iwo): 
        if len(objectNotCompared) == 1: 
            return objectNotCompared[0] 
        else: 
            return 'Insufficient data'
    else: 
        return 'Insufficient data'
  
  
# Driver code 
N = 6
Q = 3
comparisons = [ [[1, 2], '=', [5, 6]], [[1, 2, 3], '>', [4, 5, 6]], 
                                        [[3, 4], '<', [5, 6]] ] 
print(inconsistentlyWeightedObject(N, Q, comparisons)) 
输出:
4