[交互]人生第一道交互题!洛谷P1947 猜数

洛谷P1947 猜数

题目背景

这是一道交互题。

题目描述

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

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

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

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

\(k\lt x \quad k<x\),则返回 \(1\)
\(k\gt x\quad k>x\),则返回 \(−1\)
\(k=x\quad k=x\),则返回 \(0\)

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

输入格式

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

输出格式

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

输入输出样例

输入

5 5 3

输出

3 0

说明/提示

样例解释

你要猜的 \(k\)\(3\)

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

数据规模与约定

对于 \(30\%\) 的数据,保证 \(c=n-1\)
对于 \(100\%\) 的数据,保证 \(2\leq n\leq 10^6\)\(\min(20,n-1)\leq c\leq n\)

如何氵题

首先,第一道交互题,我并没有选择 IO 交互,因为现在貌似所有大考都是 grader 交互呢。(虽然容易被草过去)

做了这个题目,第一个学会的是 \(extern "C"\) 这个东西加在了一个函数的前面,那么说明这个函数是交互函数。
并且,似乎这种题目就是让你写完一个函数,然后返回一个正确的值就ok了。
在完成这个函数的同时,他会给你一些辅助函数,这些函数都是非常有用的(除非你当打 CTF 一样打 OI )。

好的,这个程序我们一行一行分析,首先第一行。

extern "C" int Seniorious(int);

明显,声明一下这个是出题人给的函数,并且这个函数是出题人给的,不是我们完善的,只需要声明就OK了。

好,然后是需要我们完成的函数。

extern "C" int Chtholly(int n,int c){
    int left=1,right=n;
    while(left<right){
        int mid=(left+right)/2;
        int pos=Seniorious(mid);
        if(pos==0){
            return mid;
            break;
        }
        if(pos==1) right=mid-1;
        else left=mid+1;
    }
    return left;
}

下一次开二分搜索的坑。

这里不着重讲二分搜索,主要讲交互题的格式之类的。

首先,声明一下这个函数叫 Chtholly 。我永远爱珂朵莉 然后呢,先定义一个\(left=1,right=n\),表示一个区间 \([L,R]\)。这个区间里应该存的是可以满足条件的数的整个数组。

好,然后这一步非常关键

    int pos=Seniorious(mid);

这一步就是说明,我现在\(pos\)来去访问一下你的\(Seniorious\)函数,然后返回一个值,交互交互,这就是向评测姬提问的过程。

然后就是朴素二分的写法,这里不多赘述。

    return left;

最后要求的答案是找到的\(k\),显然,\(k\)如果在外部的话,那这个\(k=left=right\),随便返回一个都ok了。

完结撒花!

posted @ 2021-12-03 19:37  Mercury_City  阅读(370)  评论(0编辑  收藏  举报