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
整除,那么数组就不可能是美丽的,否则如果数组mod4
的和等于零,我计算数组中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()
增加1,即count
<代码>计数以下是最小步骤数李>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,2]
,你的算法会返回什么?@n.m.难道不会是2
?@RoadRunner嗯,是的,我不懂这个程序。但随后它会为1
打印1
,因此它在另一方面似乎是错误的。@n.m.对于[1,2,3,2],您的程序也应该在[1,1,1,1]
上失败。@n.m.谢谢,非常正确。我知道他们的脚本出了问题。很好,解决方案更像python:)但是你的脚本在一些测试用例上失败了。我现在有一个工作脚本,但感谢您的输入:)