当前位置: 首页 > 知识库问答 >
问题:

算法背后的逻辑是什么

西门嘉澍
2023-03-14

我正试图从现实中解决一个问题

“偶数总和”

但是我不能这样做。下面是问题。

即使是总和也是两个玩家的游戏。玩家将获得N个正整数序列并轮流进行。在每个回合中,玩家选择一个非空切片(连续元素的子序列),使得该切片中的值之和是偶数,然后删除切片并连接序列的其余部分。第一个无法做出合法举动的玩家将输掉比赛。

如果你和你的对手玩这场游戏,你想知道你是否能赢,假设你和对手都玩得很好。你先走。

写一个函数:

字符串解(向量

如果给定一个由N个整数组成的零索引数组a,则返回一个格式为“X,Y”的字符串,其中X和Y分别是第一个和最后一个位置(包括最后一个),假设您有获胜策略,则在第一次移动时应移除这些位置以取得胜利。如果有多个这样的获胜切片,则函数应返回具有最小值X的切片。如果存在多个具有最小值X的切片,则该函数应返回最短的切片。如果您没有获胜策略,函数应返回“NO SOLUTION”。

例如,给定以下数组:

A[0] = 4 A[1] = 5 A[2] = 3 A[3] = 7 A[4] = 2

该函数应该返回“1,2”。从位置1到位置2移除一个切片后(5 ^ 3 = 8的偶数和),剩余的数组为[4,7,2]。然后对手将能够移除(偶数和4的)第一个元素或(偶数和2的)最后一个元素。然后你可以走一步,让数组只剩下[7],这样你的对手就没有合法的走法,会输。下图显示了一种可能的游戏

请注意,移除切片“2,3”(37 = 10的偶数和)也是获胜的一步,但切片“1,2”的x值较小。

对于以下数组:

A[0]=2a[1]=5a[2]=4

该函数应返回“NO SOLUTION”,因为没有策略可以保证您获胜。

假设:

N是[1..100000]范围内的整数;数组A的每个元素都是[1..1000000000]范围内的整数。复杂性:

预期最坏情况时间复杂度为O(N);预期最坏情况的空间复杂度为O(N),超出了输入存储(不包括输入参数所需的存储)。输入数组的元素可以修改。我在网上用python找到了一个解决方案。

def check(start, end):
    if start>end:
        res = 'NO SOLUTION'
    else:
        res = str(start) + ',' + str(end)

    return res

def trans( strr ):
    if strr =='NO SOLUTION':
        return (-1, -1)
    else:
        a, b = strr.split(',')
        return ( int(a), int(b) )


def solution(A):
    # write your code in Python 2.7

    odd_list = [ ind for ind in range(len(A)) if A[ind]%2==1 ] 

    if len(odd_list)%2==0:
        return check(0, len(A)-1)


    odd_list = [-1] + odd_list + [len(A)]
    res_cand = []
    # the numbers at the either end of A are even
    count = odd_list[1]
    second_count = len(A)-1-odd_list[-2]
    first_count = odd_list[2]-odd_list[1]-1
    if second_count >= count:
        res_cand.append(  trans(check( odd_list[1]+1, len(A)-1-count )))

    if first_count >= count:
        res_cand.append(  trans(check( odd_list[1]+count+1, len(A)-1 )))  

    twosum = first_count + second_count
    if second_count < count <= twosum:
        res_cand.append(  trans(check( odd_list[1]+(first_count-(count-second_count))+1, odd_list[-2] )))

    ###########################################
    count = len(A)-1-odd_list[-2]
    first_count = odd_list[1]
    second_count = odd_list[-2]-odd_list[-3]-1
    if first_count >= count:
        res_cand.append(  trans(check( count, odd_list[-2]-1 )))

    if second_count >= count:
        res_cand.append(  trans(check( 0, odd_list[-2]-count-1)) )

    twosum = first_count + second_count
    if second_count < count <= twosum:
        res_cand.append(  trans(check( count-second_count, odd_list[-3])) )



    res_cand = sorted( res_cand, key=lambda x: (-x[0],-x[1]) )

    cur = (-1, -2)
    for item in res_cand:
        if item[0]!=-1:
            cur = item

    return check( cur[0], cur[1] )

此代码有效,我无法理解一个函数到另一个函数的代码和流程。但是,我不明白算法的逻辑。它如何处理并解决问题。这可能是一项漫长的任务,但任何人都可以足够关心向我解释算法。提前致谢。


共有1个答案

葛雨华
2023-03-14

到目前为止,我已经发现奇数的数量对于找出结果至关重要。特别是计算重要值需要第一个奇数和最后一个奇数的索引。

现在我需要理解比较背后的逻辑,比如“if first_count

更新:嘿伙计们,我找到了我的问题的解决方案,并最终理解了算法的逻辑。

这个想法是基于阵列的对称性。如果阵列是对称的,我们永远也赢不了这场比赛。在这里,对称被定义为中间只有一个奇数,奇数两边的偶数相等的阵列。

如果有偶数的赔率,我们可以直接赢得比赛。

如果有奇数赔率,我们应该始终尝试使数组对称。这就是算法试图做的事情。

现在有两种情况。要么保留最后一个奇数,要么保留第一个奇数。如果你们不明白,我很乐意解释更多。谢谢

 类似资料:
  • 问题内容: 我碰到了Java行,并对它的输出感到困惑。您能否解释一下此代码背后的逻辑 输出: 问题答案: 好吧,它等效于: 真正地将原始内容显式转换为只是使其调用而不是。 我相信to 转换 实际上首先 要进行隐式加宽转换-就像这样: 这些帮助有用?

  • C++中的“using”关键字背后的逻辑是什么? 它在不同的情况下使用,我试图找到是否所有这些都有共同点,有一个原因为什么“using”关键字被这样使用。

  • 问题内容: 众所周知,某些Python的数据结构使用 哈希表 存储诸如或的项目。因此,这些对象没有顺序。但似乎,对于某些数字序列,这是不正确的。 例如,请考虑以下示例: 但是,如果我们进行一些小的更改,则无法排序: 所以问题是:Python的哈希函数如何在整数序列上工作? 问题答案: 尽管SO的问题及其顺序有很多问题,但没有人解释哈希函数的算法。 因此,这里您所需要的就是知道python如何计算哈

  • 本文向大家介绍什么是JavaScript中的逻辑运算符?,包括了什么是JavaScript中的逻辑运算符?的使用技巧和注意事项,需要的朋友参考一下 JavaScript支持以下逻辑运算符。假设变量A持有10,变量B持有20,那么, 序号 运算符和说明 1 &&(逻辑与) 如果两个操作数都不为零,则条件变为true。 例如:(A && B)是真的。 2 | | (逻辑或) 如果两个操作数中的任何一个

  • Java Integer类具有静态方法highestOneBit方法,该方法将返回一个单个一位的值,该值位于指定值中最高一位的位置,如果指定值本身等于零,则返回零。 例如,int 17的输入将返回16;因为17可以用二进制表示为10001,所以它将返回等于16的最左边的位。 在整数类中,它在Java文档中具有以下实现。 我只想知道以这种方式实现它背后的逻辑以及使用 shift 操作背后的逻辑。谁能