[交互]人生第一道交互题!洛谷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了。
完结撒花!