Run ID 作者 问题 语言 测评结果 时间 内存 代码长度 提交时间
84005 sh25_shenpy 约数倍数选卡片 Python3 解答错误 31 MS 4080 KB 5375 2026-02-05 15:39:30

Tests(0/5):


def solve(): import sys input = sys.stdin.read().split() ptr = 0 all_cards = list(map(int, input[ptr:ptr+int(input[ptr])])) ptr += len(all_cards) + 1 # 跳过第一个数字(如果有的话,但题目描述是两行) # 重新读取:第一行是所有卡片,第二行是可选数字 # 更准确的读取方式: first_line = input[ptr:ptr+int(input[ptr])] if ptr < len(input) and input[ptr].isdigit() else input[ptr:ptr+len(input)-ptr] ptr += len(first_line) second_line = input[ptr:] # 实际处理: # 第一行是所有卡片,第二行是可选数字 # 重新读取: cards = list(map(int, input[0].split())) if len(input) >=1 else [] options = list(map(int, input[1].split())) if len(input) >=2 else [] # 更准确的读取: # 根据题目描述,输入是两行,第一行是所有卡片,第二行是可选数字 # 所以应该这样读取: data = sys.stdin.read().splitlines() cards = list(map(int, data[0].split())) options = list(map(int, data[1].split())) # 确保 options 是 cards 的子集 # 但题目说明第二行的数字完全包含在第一行中,所以无需检查 # 预处理:将所有数字映射到它们的约数和倍数 # 但更高效的方式是在递归时动态计算 # 使用位掩码表示剩余的卡片 # 数字范围是1到100,所以可以用一个整数表示,每一位代表一个数字是否存在 # 初始化:将所有卡片转换为位掩码 full_mask = 0 for num in cards: full_mask |= 1 << (num - 1) # 可选数字的集合 option_set = set(options) # 记忆化字典:key是 (mask, last_num), value是能否必胜 memo = {} def can_win(mask, last_num): if (mask, last_num) in memo: return memo[(mask, last_num)] # 生成当前可选的数字:last_num的约数或倍数,且在mask中 current_options = set() if last_num == -1: # 第一次选择,可选任何数字 for num in options: if mask & (1 << (num - 1)): current_options.add(num) else: # 约数 for d in range(1, last_num): if last_num % d == 0: if mask & (1 << (d - 1)): current_options.add(d) # 倍数 for m in range(last_num * 2, 101): if mask & (1 << (m - 1)): current_options.add(m) # 还需要确保这些数字在选项中?题目描述似乎不需要,因为可选数字是第二行的子集,但游戏规则是任何约数或倍数 # 但题目说“可以选的数字必须完全包含在第一行的数字中”,即第二行的数字是第一行的子集 # 但游戏规则是下一步必须选约数或倍数,无论是否在第二行中? # 根据题目描述:“第二行的数字必须完全包含在第一行的数字中”,但游戏规则是下一步可选的是前一个数字的约数或倍数,且这些数字必须在剩余的卡片中。 # 所以可选的数字是剩余卡片中是前一个数字的约数或倍数的数字,不一定是第二行的数字。 # 但第二行的数字是初始可选的数字,即第一步只能选第二行的数字。 # 所以需要明确: # 第一步:只能选第二行的数字(且在剩余卡片中) # 后续步骤:选前一个数字的约数或倍数,且在剩余卡片中 # 所以上面的代码需要调整: pass # 重新定义:第一步只能选 options 中的数字,且在 mask 中 # 后续步骤:选 last_num 的约数或倍数,且在 mask 中 if last_num == -1: current_options = set() for num in options: if mask & (1 << (num - 1)): current_options.add(num) else: current_options = set() # 约数 for d in range(1, last_num): if last_num % d == 0: if mask & (1 << (d - 1)): current_options.add(d) # 倍数 for m in range(last_num * 2, 101): if mask & (1 << (m - 1)): current_options.add(m) if not current_options: memo[(mask, last_num)] = False return False for num in sorted(current_options): new_mask = mask ^ (1 << (num - 1)) if not can_win(new_mask, num): memo[(mask, last_num)] = True return True memo[(mask, last_num)] = False return False # 第一次选择,last_num = -1 candidates = [] for num in options: if full_mask & (1 << (num - 1)): # 模拟选择这个数字 new_mask = full_mask ^ (1 << (num - 1)) if not can_win(new_mask, num): candidates.append(num) if candidates: print(min(candidates)) else: print(-1) solve()


测评信息: