Python 美丽的序列

Python 美丽的序列,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,如果一个整数序列的每个元素都可以被4整除,那么它就是一个美丽的序列。给你一个序列a1,a2,…,an。在一个步骤中,您可以选择该序列的任意两个元素,将它们从序列中删除,并将它们的总和附加到序列中。计算使给定序列美观所需的最小步骤数,如果不可能,则打印-1 for i in range(int(input())): n=int(input()) arr=list(map(int,input().split())) if((sum(arr))%4)!=0: p

如果一个整数序列的每个元素都可以被
4
整除,那么它就是一个美丽的序列。给你一个序列
a1,a2,…,an
。在一个步骤中,您可以选择该序列的任意两个元素,将它们从序列中删除,并将它们的总和附加到序列中。计算使给定序列美观所需的最小步骤数,如果不可能,则打印
-1

for i in range(int(input())):
    n=int(input())
    arr=list(map(int,input().split()))
    if((sum(arr))%4)!=0:
        print(-1)
        continue
    else:
        counter=[]
        for i in range(n):
            if arr[i]%4!=0:
                counter.append(arr[i])
            else:
                continue

        x=sum(counter)
        while(x%4==0):
            x=x//4

        print(x)
我的方法是:如果数组的和不能被
4
整除,那么数组就不可能是美丽的,否则如果数组mod
4
的和等于零,我计算数组中mod by 4不等于零的元素,并将它们附加到列表中,然后找到列表的和,并将和除以4,直到其值为零商模4不等于零。我做错了什么

编辑:我有一个很好的工作脚本

for i in range(int(input())):
    n=int(input())
    arr=list(map(int,input().split()))
    count1=0
    count2=0
    count3=0
    summ=0
    for i in range(n):
        x=arr[i]%4
        summ+=x


        if x==1:
            count1+=1

        if x==2:
            count2+=1

        if x==3:
            count3+=1
    if (summ%4)!=0:
        print(-1)
        continue

    else:


        if count2==0 and count1!=0 and count3==0:
            tt=count1//4
            print(3*tt)

        if count2==0 and count1==0 and count3!=0:
            tt=count3//4
            print(3*tt)

        if count2%2==0 and count1==count3:
            print(count2//2+count1)

        flag1=min(count1,count3)
        flag2=abs(count1-count3)

        if count2%2==0 and count1!=count3:

            flag3=flag2//4
            flag4=flag3*3

            print(count2//2+ flag1+ flag4)

        if count2%2!=0 and count1!=count3:
            flag3=flag2-2
            flag4=flag3//4
            flag5=flag4*3


            print(((count2-1)//2)+flag1+flag5+2)

我不完全确定你的问题是什么,但也许你可以改变你处理这个问题的方法。你的逻辑似乎很好,但似乎你试图一次完成所有事情,如果你把它分解成几部分,这个问题会容易得多。它看起来非常适合分而治之/递归方法。我还冒昧地自己解决了这个问题,因为这似乎是一个有趣的问题

以下建议

您可以做的第一件事是编写一个函数,查找两个总和可被
k
整除的数字,并返回它们:

def two_sum(numbers, k):
    n = len(numbers)

    for i in range(0, n):
        for j in range(i+1, n):
            if (numbers[i] + numbers[j]) % k == 0:
                return numbers[i], numbers[j]
    return None
此外,上面的函数是O(n^2),这可以提高效率

其次,您可以编写一个使用上述函数的递归函数,并且有一个基本情况,即当列表中的所有数字都可以被
k
整除时,它停止递归,因此列表变得“漂亮”。以下是一种方法:

def rec_helper(numbers, k, count):
    if all(x % k == 0 for x in numbers):
        return count

    # probably safer to check if two_sum() is not None here
    first, second = two_sum(numbers, k)

    numbers.remove(first)
    numbers.remove(second)
    numbers.append(first + second)

    return rec_helper(numbers, k, count + 1)
上述代码的程序

>>> beautiful_array([1, 2, 3, 1, 2, 3, 8], 4)
3
>>> beautiful_array([1, 3, 2, 2, 4, 8], 4)
2
>>> beautiful_array([1, 5, 2, 2, 4, 8], 4)
-1
  • 基本情况:如果列表中的所有项目当前都可被
    k
    整除,则返回当前累计的
    计数
  • 否则,从
    two\u sum()
  • remove()
    将这两个数字从列表中删除,并将它们追加到列表的末尾
  • 最后,再次调用
    rec\u helper()
    ,将新修改的列表和
    count
    增加1,即
    count+1
    <代码>计数
    以下是最小步骤数
最后,您现在可以编写一个主调用函数:

def beautiful_array(numbers, k):
    if sum(numbers) % k != 0:
        return -1

    return rec_helper(numbers, k, 0)
它首先检查列表中数字的
sum()
是否可被
k
整除,然后继续调用
rec\u helper()
。如果未通过此测试,则函数将简单地返回
-1
,并且列表不能变得“漂亮”

上述代码的行为

>>> beautiful_array([1, 2, 3, 1, 2, 3, 8], 4)
3
>>> beautiful_array([1, 3, 2, 2, 4, 8], 4)
2
>>> beautiful_array([1, 5, 2, 2, 4, 8], 4)
-1

注意:以上代码示例只是建议,您可以按照自己的意愿使用。它也不处理
输入()
,因为我认为代码中的主要问题是方法。我不想创建一个全新的解决方案来处理您的输入。如果他们的上述代码有问题,或者您不理解任何内容,请在下面进行评论

首先是一些观察:

  • 为了4-可除性,我们可以用它们的4-除余数替换所有数字,因此我们只需要处理值0、1、2和3
  • 顺序无关紧要,数一数零、一、二、三就足够了
  • 有几对直接给出一个可被4整除的和:(1,3)和(2,2)。这样一对的每一个存在都需要一个步骤
  • 有三元组(1,1,2)和(3,3,2)需要两个步骤
  • 有四个(1,1,1,1)和(3,3,3,3)需要三个步骤
算法:

  • 计算余数-0(可以省略)、余数-1、余数-2和余数-3
  • 如果总数(来自计数)不能被4整除,则没有解决方案
  • 对于上面描述的所有N元组,找出它们适合计数的频率;将结果步骤数相加,从计数中减去消耗的数字
最后,余数-1、余数-2和余数-3计数应为零。

这里是一个O(N)实现,它基本上按照以下建议的方向进行:


问题:对于
[1,2,3,2]
,你的算法会返回什么?@n.m.难道不会是
2
?@RoadRunner嗯,是的,我不懂这个程序。但随后它会为
1
打印
1
,因此它在另一方面似乎是错误的。@n.m.对于[1,2,3,2],您的程序也应该在
[1,1,1,1]
上失败。@n.m.谢谢,非常正确。我知道他们的脚本出了问题。很好,解决方案更像python:)但是你的脚本在一些测试用例上失败了。我现在有一个工作脚本,但感谢您的输入:)