洛谷:P1947 猜数

时间限制1.00s         内存限制128.00MB         难易度:普及−

【题目背景】

这是一道交互题

【题目描述】

珂愛给了你一个 [1,n]之间的整数 k,你每次可以询问一个整数 x,然后珂愛会告诉你 x 和 k 的大小关系。

你需要用尽可能少的次数猜出珂愛想的数。

你需要实现一个函数 int Chtholly(int n,int c),这个函数的作用是在不超过 c 次询问中猜对 [1,n] 中的一个数,返回值为你最终确定的数。

你可以调用交互库中一个叫做 Seniorious 的函数,其原型为 int Seniorious(int x),返回值为:

  • 若 k<x,则返回 1。
  • 若 k>x,则返回 −1。
  • 若 k=x,则返回 0。

你调用 Seniorious 函数的次数不超过 c 才能得到这个点的分数,否则这个点为 0 分。有关该函数的调用请参考【说明/提示】部分。

由于珂愛只会写 C++ 语言的交互库,所以你只能使用 C++ 语言(包括 C++,C++11,C++14,C++17)来解决本题。

【输入格式】

样例输入中三个数分别为 n,c,k。这些数据你都无法读取

【输出格式】

样例输出中第一个数是你猜的 k,第二个数是你调用 Seniorious 函数的次数。这些数据你不必输出

【输入输出样例】

输入 #1

5 5 3

输出 #1

3 0

【说明/提示】

样例解释

你要猜的 k 为 3。

由于你和珂愛心灵相通,所以在没有调用 Seniorious 的情况下就猜出来了。

数据规模与约定
  • 对于 30% 的数据,保证 c=n−1。
  • 对于 100% 的数据,保证 2≤n≤10^6,min(20,n−1)≤c≤n。
提示

关于交互题

样例交互库源代码链接注意,此交互库仅供测试样例使用,实际评测时的交互库此交互库不同

如果您不知道如何在本地调试您的代码,请参考这篇文章

请特别注意,你的答案应该作为函数的返回值给出,你不需要,也不应该向标准输出输出任何内容,否则将无法获得分数

如果有需要,你可以在选手程序的开头加入一些头文件,当然在本题中这并不是必须的。

交互库给出的函数 Seniorious 无法直接调用,需要在选手程序中用 extern "C" 关键字声明一次。

下面给出本题的模板程序(请不要使用 gcc9 提交):

#include <cstdio>                         // 在本题中并不是必须的

extern "C" int Seniorious(int);           // 在这里需要声明一次交互库给出的函数。

extern "C" int Chtholly(int n, int OvO) { // 在这里实现交互库要求你实现的函数。
  int ans = 1;
  for (int l = 1, r = n, mid = (l + r) >> 1; l <= r; mid = (l + r) >> 1) if (Seniorious(mid) >= 0) {
    r = (ans = mid) - 1;
  } else {
    l = mid + 1;
  }
  return ans;
}

【算法分析】

设当前数字的可能区间为 [L,R],我们取 mid=(L+R)/2,如果猜的偏大,说明答案在 [L,mid-1]范围内,否则在 [mid+1,R]区间内,这道题目是经典的二分找数问题。但这勾8的交互题是个什么鬼,研究了两年半都没搞懂(不用在意细节)。

【参考代码】 

#include<bits/stdc++.h>
using namespace std;
extern "C" int Seniorious(int x);
extern "C" int Chtholly(int n,int c)
{
    int l=1,r=n;
    while(1)
    {
        int mid=(l+r)/2;
        int res=Seniorious(mid);
        if(res==1) r=mid-1;
        else if(res==-1) l=mid+1;
        else return mid;
    }
    return 0;
}

  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值