闲暇时,福尔摩斯和华生玩一个游戏:
在N张卡片上写有N个整数。两人轮流拿走一张卡片。要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数。例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括:
1,2,3, 6,12,18,24 …
当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方。
请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜!
当选多个数字都可以必胜时,输出其中最小的数字。如果无论如何都会输,则输出-1。
输入数据为2行。第一行是若干空格分开的整数(每个整数介于1~100间),表示当前剩余的所有卡片。
第二行也是若干空格分开的整数,表示可以选的数字。当然,第二行的数字必须完全包含在第一行的数字中。
程序则输出必胜的招法!!
例如:
用户输入:
2 3 6
3 6
则程序应该输出:
3
再如:
用户输入:
1 2 2 3 3 4 5
3 4 5
则程序应该输出:
4
博弈论
先分析下必胜态和必败态,如果我拿了一张牌,并且没有其他的约数或倍数可拿,显然这是我的必胜态。如果在这之前,对方也拿了一张牌,显然对他来说他拿的那张牌就是必败态,所以这种博弈里,必胜态和必败态是交替出现的。
但要确定是必败还是必胜,不抽到最后一张还是不能确定,所以要把所有可能的抽卡情况搜索出来,只有确定抽了这张牌,之后所有的情况都是必败,我才能确定这张牌是必胜。
Code
def dfs(x):
vis[x] = True
for k in range(len(get[x]) - 1, -1, -1):
if not vis[get[x][k]] and dfs(get[x][k]):
vis[x] = False
return False
vis[x] = False
return True
if __name__ == '__main__':
nums1 = list(map(int, input().split()))
nums2 = list(map(int, input().split()))
length1, length2, get, vis = len(nums1), len(nums2), [[] for _ in range(200)], [False] * 200
for i in range(length1):
for j in range(i):
if nums1[i] % nums1[j] == 0 or nums1[j] % nums1[i] == 0:
get[i].append(j)
get[j].append(i)
for i in range(length2):
for j in range(length1):
if nums2[i] == nums1[j] and dfs(j):
print(nums1[j])
break
else:
continue
break
else:
print(-1)
可惜只能拿到60分,暂时没有什么更好的办法。