LG8481
题意
这题花了我好长时间才看明白。
一道二分查找题。每次查找一个数 \(t\)(保证一定能找到),每次 \(\operatorname{mid}\) 可以取 \(\left\lfloor\dfrac{(l+r)}{2}\right\rfloor\) 或 \(\left\lfloor\dfrac{(l+r+1)}{2}\right\rfloor\),求最少需要多少次可以定位到 \(t\) 的位置。
分析
看到查询次数 \(q \le 100\),就立马想到了用搜索。
因为题目程序中 \(w\) 的取值有两种可能,即 \(0\) 和 \(1\),所以可以分别令 \(w_1=0\) 和 \(w_2=1\),分别将 \(w_1\) 和 \(w2\) 代入题目程序中的 \(w\),并进行二分,递归下去即可。
由于最多定位次数不超过 $ \log_2 n$ 次,每一次有两种情况,所以时间复杂度即为 \(O(2^{\log_2 n} \times q)=O(nq)\),似乎有点危险,但洛谷评测机却跑得飞快。
代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
int n,a[2000001],q,t,cnt;
template<typename ty=int>
inline ty read()
{
ty n=0;char c=getchar();bool fl=0;
while(c<33&&c!='-') c=getchar();
if(c=='-') fl=1,c=getchar();
while(c>='0'&&c<='9')
{
n=n*10+(c^48);
c=getchar();
}
return fl?-n:n;
}
template<typename ty>
void pr(ty x)
{
if(!x) return ;
pr(x/10);
putchar(x%10^48);
}
template<typename ty>
inline void write(ty x)
{
if(x==0) putchar('0');
else if(x<0) putchar('-'),x=-x;
pr(x);
putchar('\n');
}
void dfs(int l,int r,int x,int k)
{
if(l==r)
{
cnt=min(cnt,k);
return;
}
int m1=(l+r)/2,m2=(l+r+1)/2;
if(a[m1]<x) dfs(m1+1,r,x,k+1);
else dfs(l,m1,x,k+1);
if(a[m2]-1<x) dfs(m2,r,x,k+1);
else dfs(l,m2-1,x,k+1);
return;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
q=read();
for(int i=1;i<=q;i++)
{
t=read();
cnt=20;
dfs(1,n,t,0);
write(cnt);
}
return 0;
}
还是菜。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现