#P14597. [Bulgarian2025秋季赛]mummy

[Bulgarian2025秋季赛]mummy

题目描述

木乃伊阿木木要面对一支由 NN 个对手组成的奇怪队伍。每个对手都选择了一个不同的英雄(编号为 00N1N-1),并且每个人还会打一个不同的位置(位置同样编号为 00N1N-1)。

阿木木并不知道“哪个英雄对应哪个位置”,但他很想知道。为此,他可以进行若干次询问:

  • 每次询问中,他给出一个完整猜测,即为每个位置指定一个英雄;
  • 系统会告诉他,这个猜测中有多少个位置猜对了。

形式化地说,你需要猜出一个隐藏排列。每次询问也是一个排列,返回值为它与隐藏排列中相同位置上相同元素的个数。你的目标是在保证一定能猜出答案的前提下,尽可能减少平均询问次数。

请编写程序 mummy 来完成此任务。

实现细节

你需要实现如下函数:

std::vector<int> findPerm(int N)
  • N:隐藏排列的长度。

该函数在每个测试中会被调用 TT 次,每次对应一个子测试,且这些子测试的 NN 相同。你需要返回隐藏排列。

为了获取信息,你可以调用评测器提供的函数:

int numMatches(const std::vector<int>& perm);
  • perm:一次询问所提交的排列,必须是 0,1,,N10,1,\dots,N-1 的一个合法排列。

该函数返回 perm 与隐藏排列在相同位置上相同元素的个数。

说明

这是一个函数实现题 / 查询题,不是普通的标准输入输出题。你提交的代码只需要实现上面的函数,不需要自行读入隐藏排列。

约束条件

  • 1N5001 \le N \le 500
  • T=25T = 25

子任务与评分

子任务 分值 NN
1 9 6
2 15 44
3 7 155
4 22 300
5 47 500

每个子任务恰好包含一个测试点,其中又包含 T=25T=25 个规模相同的子测试。只有当该子任务中的所有隐藏排列都被正确猜出时,才能获得该子任务的分数。

设某个子任务中平均询问次数为 QQ,则该子任务得到的分数比例为:

3700max(Q,3700)\frac{3700}{\max(Q,3700)}

也就是说,平均询问次数越少,得分越高;当 Q3700Q \le 3700 时可以获得该子任务满分。

样例交互

假设 N=4N=4,隐藏排列为:

1 3 2 0

一次可能的交互如下:

你的程序 评测器
findPerm(4)
numMatches({0,1,2,3}) 返回 1
numMatches({3,2,1,0})
numMatches({0,2,3,1}) 返回 0
numMatches({1,3,0,2}) 返回 2
返回 {1,3,2,0}

在这个例子中,你的程序总共使用了 44 次询问,成功找到了隐藏排列。

本地评测器格式

输入格式

  • 第一行两个整数 N,TN,T,表示排列大小和子测试数量;
  • 接下来第 22 行到第 T+1T+1 行,每行给出一个长度为 NN 的排列,表示对应子测试中的隐藏排列。

输出格式

  • 输出一行:
    • 如果某个子测试猜错,则输出错误信息;
    • 如果所有子测试都猜对,则输出这些子测试的平均询问次数。