问题在于使用DNA链可以形成多少完整的结构。规则是,新零件的第一个字母必须与上一个链的最后一个字母相同。
在第一行上给您一个整数:链数。接下来的n行是字符串:链。
示例:
5
ACGA
ACGA
ACAC
CCCC
CTAC
输出: 4
我尝试了递归回溯解决方案,但有时会得到错误的答案。我似乎无法找出问题所在。
ans = 0
used = {}
def place(howmanyplaced, allowedletter):
global ans
if howmanyplaced == num:
ans += 1
return ans
for i in range(0, len(mylist)):
if mylist[i][0] == allowedletter and used[i] == False:
allowedletter = mylist[i][-1]
used[i] = True
place(howmanyplaced+1, allowedletter)
used[i] = False
num = int(input())
mylist = []
for l in range(0, num):
i = input()
used[l] = False
mylist.append(i)
for k in range(0, len(mylist)):
used[k] = True
place(1, mylist[k][-1])
used[k] = False
print(ans)
答案 0 :(得分:1)
我对您代码的主要关注是如何在此循环中修改allowedletter
:
if mylist[i][0] == allowedletter and used[i] == False:
allowedletter = mylist[i][-1]
used[i] = True
place(howmanyplaced+1, allowedletter)
由于您是通过递归而不是迭代来链接序列,因此allowedletter
不应在此循环中进行修改。使用其他变量。以下是我对您的程序的修复,以解决此问题并重新考虑了代码样式:
def place(how_many_placed=0, allowed_letter=None):
if how_many_placed == number:
return 1
answer = 0
for i, sequence in enumerate(sequences):
if not used[i] and (allowed_letter is None or sequence[0] == allowed_letter):
used[i] = True
answer += place(how_many_placed + 1, sequence[-1])
used[i] = False
return answer
number = int(input())
sequences = []
used = []
for _ in range(number):
sequences.append(input())
used.append(False)
print(place())
看看这对您是否更好。
答案 1 :(得分:0)
如果可以使用numpy,这是向量化的解决方案。 np.roll
移动列表,以便您可以将下一个元素的第一个字母与上一行的最后一个字母进行比较。
import numpy as np
l = ['ACGA', 'ACGA', 'ACAC', 'CCCC', 'CTAC']
a = np.array(l)
last_letter= np.roll(a,1)[1:].view('<U1')[::len(a[-1])]
first_letter = a.view('<U1')[::len(a[0])][:-1]
sum(last_letter==first_letter)
#returns 4