这个问题由Google在最近的一轮codejam回合中提出,它仍然困扰着我如何设法解决它。请告诉我该怎么做:
去,去,电源安排器!每个人都喜欢这支由五个超级英雄组成的团队 戴着字母A,B,C,D和E的高中生 并排面对邪恶的怪物,他们安排他们的团队 以120种可能的左右顺序之一进行分配 各种不同的战术超级大国。他们更受欢迎 比忍者神龟!
该节目的一些评论家声称该团队只有安排 头,使演出的所有人可以卖出120套各5套 行动人物,每个人物都以不同的团队为特色 从左到右的顺序,粘贴到基础上,以便不能 重新排列。作为狂热的Power Arrangers粉丝,您已经收集了119个 这些集合,但是您不记得丢失了哪些集合。您的 沿着架子水平排列119套 从左到右顺序总共有119×5 = 595个可动人偶。你做 不记得这些安排是如何安排的,但是您知道 集合的置换是从所有样本中随机随机选择的 可能的排列,并且对于每种情况都是独立的。
您不想浪费任何时间弄清楚自己是哪一套 缺少,因此您打算查看最多F个数字上的字母 架子。例如,您可以选择查看广告上的字母 左边的第八位数字,这将是左边的第三位数字 从左数第二个数中左移。看人物的时候 只从那一个数字得到信件;字母很难看 和其他团队成员看起来非常相似!
最多检查F个数字后,您必须找出哪个 缺少套,因此您可以完成收藏并准备好 面对任何可能的邪恶威胁!
输入和输出
这是一个互动问题。您应该确保已阅读 常见问题解答中“互动问题”部分中的信息。
最初,您的程序应读取包含两行的一行 整数T(测试用例数)和F(数字) 允许每个测试用例进行检查。然后,您需要进行T检验 案例。
在每个测试用例中,统一选择丢失的一组图形 从所有可能的集合中随机抽取,其余集合的顺序 同样从所有可能的顺序中随机选择。每一个 选择是独立于所有其他选择和您的输入的。
在每个测试用例中,您的程序将最多处理F +1次交换 与我们的法官。您可以组成以下形式的F个交易所:
- 您的程序输出一行,其中包含1到595之间(包括1和595)的单个整数,指示哪个数字(从左到右的顺序) 沿着架子)。再举一个例子,589 代表第二组中从左数的第四个数字 是的。
- 法官用一行包含一个大写字母A,B,C,D或E的行作为回应,指出该图上的字母。如果你 发送了无效数据(例如,数字超出范围或行格式错误), 法官将改为以单行回应 大写字母N。
然后,在完成与您一样多的上述F交换之后 如果需要,您必须再次交换以下格式:
- 您的程序输出一行包含五个大写字母的单个字符串:对应于缺失集合的排列 (例如CADBE)。
- 法官的回答是一行包含一个大写字母:如果回答正确,则为Y;否则,为N(或 提供了格式错误的行)。如果收到Y,则应开始 下一个测试用例,如果没有更多测试用例,则停止发送输入。
法官将N发送到您的输入流后(因为 无效的数据或错误的答案),它将不会发送其他任何信息 输出。如果您的程序继续等待之后的判断 收到N,您的程序将超时,从而导致时间限制 超出错误。请注意,您有责任 程序及时退出以收到错误答案的判断,而不是 超过时间限制错误。与往常一样,如果超出了内存限制, 或程序出现运行时错误,您将收到相应的 判断。限制
1≤T≤50。时间限制:每个测试装置40秒。内存限制:1GB。 选择缺少的集以及其余集的顺序 均匀且独立地随机。测试集1(可见)
F =475。测试仪2(隐藏)
F = 150。
答案 0 :(得分:4)
您可以尝试这样的事情:
这样,您将需要119 + 23 + 5 + 1 = 148个查询才能找到丢失的排列。
Python中的示例实现:
import itertools, random, collections
permutations = list(itertools.permutations("ABCDE"))
random.shuffle(permutations)
permutations.pop()
flat_permutations = [c for p in permutations for c in p]
queries = 0
candidates = [i * 5 for i in range(119)]
missing = ""
for i in [0, 1, 2, 4]:
where = collections.defaultdict(list)
for t in candidates:
queries += 1
c = flat_permutations[t + i]
where[c].append(t)
c, candidates = min(where.items(), key=lambda item: len(item[1]))
missing += c
# we queried for the 5th and used it as 4th in 'missing'
missing += next(c for c in "ABCDE" if c not in missing)
print("queries", queries)
print("missing", missing)
print("correct?", tuple(missing) not in permutations)
这将总是找到丢失的排列,但也会总是 1)进行148个查询。
如果F较小,则可以只查询随机位置,然后使用概率来猜测最不适合这些猜测的排列。
1)从技术上讲,您可以以更少的查询找到它,例如如果您非常幸运,并且经过100次查询后,您已经拥有4个字母,每个字母有24个职位,那么您不需要再执行最后19个查询,但这纯粹是个好运,而且机会很小。