题目描述
给出一些不重复的数字,两人轮流选数字,规则要求后一次选的数字,和前一次选的数字不能互质。现在给出小A第一次选的数字X,问在游戏过程中,某个数字Y能否被选出?如果能,请输出两人至少需要选出几个数字?如果不能,请输出-1。
简单实现
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ***************************************************************************
#
# Copyright (c) 2017 ByteDance.com, Inc. All Rights Reserved
#
# *************************************************************************/
#
# @file main.py
#
# @date 2018/6/4
#
import Queue
CURR_NUM = "curr_num"
STATUS = "status"
STEP = "step"
def gcd(b, a):
'''
辗转相除求最大公约数
:param b:
:param a:
:return:
'''
b, a = a, b % a
if a == 0:
return b
else:
return gcd(b, a)
def select(status, x, y):
'''
从数组arr中,从x到y,按照游戏规则次数最小
:param arr:
:param x:
:param y:
:return:
'''
def new_status(curr, status, step):
'''
创建新状态
:param curr:
:param visited:
:param step:
:return:
'''
return {
CURR_NUM: curr,
STATUS: status,
STEP: step,
}
# res
res = -1
finish_status = None
queue = Queue.LifoQueue()
# push
curr_status = status
curr_status[x] = 1
queue.put(new_status(x, curr_status, 1))
# bfs
while (not queue.empty()):
top = queue.get()
curr_num = top[CURR_NUM]
curr_step = top[STEP]
curr_status = top[STATUS]
if curr_num == y:
if res == -1 or res > curr_step:
res = curr_step
finish_status = curr_status.copy()
continue
else:
for k, v in curr_status.items():
if v == 0 and gcd(k, curr_num) != 1:
# next_status
next_status = curr_status.copy()
next_status[k] = 1
# next_num
next_num = k
# next_step
next_step = curr_step + 1
queue.put(new_status(next_num, next_status, next_step))
print finish_status, res
return res
if __name__ == '__main__':
'''
main
'''
print select({3: 0, 5: 0, 15: 0}, 3, 5)
print select({3: 0, 5: 0}, 3, 5)
print select({3: 0, 15: 0, 2: 0, 4: 0, 12: 0, 20: 0}, 3, 20)