题解 | 24点游戏算法
import sys from fractions import Fraction from typing import List,Set def get_vals(a_set:Set[Fraction], b_set:Set[Fraction]) -> List[Set[Fraction]]: vals = set() for a in a_set: for b in b_set: vals.add(a + b) vals.add(a * b) vals.add(a - b) vals.add(b - a) if b != 0: vals.add(a / b) if a != 0: vals.add(b / a) return [vals] def dfs(nums:List[Set[Fraction]]) -> List[Set[Fraction]]: if len(nums) == 1: return 24 in nums[0] length = len(nums) for i in range(length): for j in range(i + 1, length): a, b = nums[i], nums[j] visited = [0] * length visited[i] = 1 visited[j] = 1 vals = get_vals(a, b) not_visited = [nums[k] for k in range(length) if visited[k] == 0] nums2 = vals if len(not_visited) == 0 else vals + not_visited if dfs(nums2): return True return False raw_input = [] for i,line in enumerate(sys.stdin): raw_input.append(line.strip()) if i == 1: break num_lst = [set([Fraction(i)]) for i in raw_input[0].split(' ')] if dfs(num_lst): print('true') else: print('false')
代码如上:
- 使用dfs计算所有可能的结果, dfs输入参数为一个list, list由set组成, set由数字组成
- 如果list长度为1, 则检查set中是否有数字的值等于24, 有则返回true
- 如果list长度大于1, 从list中选择两个元素(两个set), 使用get_vals函数计算这两个set中的数字经过四则运算后可能产生的数值.
- 将第3步中计算的数值与剩余元素(如果有), 组成一个新的list, 输入dfs进行计算
- 使用分数进行计算,也可以使用小数, 将判断条件修改为`abs(num - 24) < 1E-6`即可