#P15657. [Bulgarian2025训练营]Hidden隐藏数

[Bulgarian2025训练营]Hidden隐藏数

Hidden(隐藏数)

题目背景

有一个整数隐藏在区间 [1,n][1,n] 中。你不知道这个数是多少,需要通过询问来猜出它。

每次你可以询问一个整数 xx,评测器会告诉你:

  • 你猜中了;
  • 你猜的数比隐藏数大;
  • 你猜的数比隐藏数小。

但是评测器非常“懒”:ii 次询问的答案,会在你提出第 i+1i+1 次询问时才返回。也就是说,答案总是延迟一轮。

你需要在至多 tt 次询问内确定隐藏数。

本题为 函数提交题。选手不需要、也不应当编写 main 函数,不要从标准输入读入,也不要向标准输出输出。


需要实现的函数

你需要实现如下函数:

void play(int n, int t);

含义如下:

  • n:隐藏数所在区间为 [1,n][1,n]
  • t:最多允许调用 guess 的次数。

你可以在 play 中调用如下函数进行询问:

int guess(int x);

guess(x) 的含义如下:

  • 你本次提出询问 xx
  • 第一次调用 guess 时,由于没有上一轮询问,因此一定返回 -2
  • 从第二次调用开始,返回的是上一次询问的答案:
    • 返回 -1:上一次询问的数比隐藏数大;
    • 返回 +1:上一次询问的数比隐藏数小;
  • 如果上一次询问的数正好等于隐藏数,交互会立刻结束,你会根据子任务和询问次数获得分数。

也就是说,如果你调用:

int r = guess(x);

那么 r 不是当前 xx 的结果,而是前一次询问的结果。


提交格式

你的程序需要包含头文件:

#include "hidden.h"

在 Hydro OJ 的本配置中,选手代码末尾还需要包含正式 grader:

#include "grader.cpp"

完整提交形式如下:

#include "hidden.h"
#include <bits/stdc++.h>
using namespace std;

void play(int n, int t) {
    // 在这里实现你的策略
}

#include "grader.cpp"

请注意:

  • 不要编写 main 函数;
  • 不要读标准输入;
  • 不要向标准输出输出任何内容;
  • 所有询问都必须通过 guess(x) 完成。

约束与子任务

子任务 分数 nn tt 额外限制
0 - 样例
1 6 55 66
2 77 55
3 21 5050 99
4 9 350350 1313
5 12 25002500 1717
6 20 3×1053\times 10^5 2727
7 26 10910^9 100100

除最后一个子任务外,只有通过该子任务所有测试点才会得到该子任务分数。

对于最后一个子任务,记你使用的询问次数为 QQ。本 Hydro 配置按原 checker 的比例计分:

  • Q44Q \le 44,该子任务满分;
  • 45Q10045 \le Q \le 100,该子任务按比例给分,比例约为 (45Q)3\left(\dfrac{45}{Q}\right)^3
  • Q>100Q>100,不得分。

样例说明

假设评测器调用:

play(5, 6)

隐藏数在 [1,5][1,5] 中,最多允许 6 次询问。

一种可能的过程如下,其中返回值总是上一轮询问的结果:

选手调用 返回值 说明
guess(3) -2 第一次调用,没有上一轮询问
guess(2) +1 上一次询问 3 小于隐藏数
guess(5) 上一次询问 2 小于隐藏数
guess(4) -1 上一次询问 5 大于隐藏数
guess(1) 交互结束 上一次询问 4 正好等于隐藏数

注意:即使你已经在上一轮询问中猜中了隐藏数,也还需要再调用一次 guess,评测器才会返回上一轮的结果并结束交互。


本地测试

原包提供了 Lgrader.cpp 用于本地简单测试。若使用本地 grader,输入格式为:

n t x

其中 xx 是隐藏数。

本 Hydro 配置使用正式 grader.cpp,测试数据中还包含随机种子和自适应评测参数,选手不需要关心这些内容。

@下发文件