'''
FIFA 世界杯对足球爱好者而言是四年一度的盛事。下面我们拿
2014 年世界杯参赛国的国名做个词语接龙游戏。不过,这里用的不是中
文,而是英文字母(忽略大小写)。
假设每个国名只能使用一次,求能连得最长的顺序,以及相应的国名个数。
'''
# 设置一个保存世界杯参赛国的数组
country = ("Brazil", "Croatia", "Mexico", "Cameroon",
"Spain", "Netherlands", "Chile", "Australia",
"Colombia", "Greece", "Cote d'Ivoire", "Japan",
"Uruguay", "Costa Rica", "England", "Italy",
"Switzerland", "Ecuador", "France", "Honduras",
"Argentina", "Bosnia and Herzegovina", "Iran",
"Nigeria", "Germany", "Portugal", "Ghana",
"USA", "Belgium", "Algeria", "Russia",
"Korea Republic")
#回溯算法计算国名接龙
def search(ans): #ans存储了接龙队列中的国名
global max_ans
#temp_lib存储了所有后续可用的国名
temp_lib = [i for i in range(len(country))
if ans[-1][-1].upper()==country[i][0] and not is_used[i]]
if not temp_lib: #无法继续接龙,则更新最优解
if len(ans) > len(max_ans):
max_ans = ans[:]
else:
for pos in temp_lib: #遍历所有后续可用的国名
is_used[pos] = True #标记下标为pos的国名已用
ans.append(country[pos])#将country[pos]加入接龙队列
search(ans) #递归继续接龙游戏
del ans[-1] #将country[pos]从接龙队列取出,以便后面可以加入队列
is_used[pos] = False #标记下标为pos的国名未用
def dfs(ans):
global max_ans, lib
last = ans[-1][-1].upper()#提取当前接龙队列末尾国名的结尾字母并转换成大写
arr = [k for k, v in lib[last].items() if v]#arr存储了所有后续可用的国名
if arr:
for c in arr: #遍历所有后续可用的国名
ans.append(c) #将国名c加入接龙队列
lib[last][c] = False #标记国名c已用
dfs(ans)
del ans[-1] #将国名c从接龙队列取出,以便后面可以加入队列
lib[last][c] = True #标记国名c未用
else:
if len(ans) > len(max_ans):
max_ans = ans[:]
is_used = [False] * len(country)
max_ans = []
for i in range(len(country)):
ans = [country[i]]
is_used[i] = True
search(ans)
is_used[i] = False
print(max_ans)
lib = {}
#以大写字母作为键,每个字典的值又是一个字典
for k in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
lib[k] = {}
#把首字母与键相同的国名加入值字典,每个二重字典以国名为键,其值初始化为True,表示尚未加入队列,均可用
for c in country:
lib[c[0]][c] = True
max_ans, ans = [], []
for c in country:
ans.append(c)
lib[c[0]][c] = False
dfs(ans)
del ans[-1]
lib[c[0]][c] = True
print(max_ans)