2971:抓住那头牛
- 题目链接:http://noi.openjudge.cn/ch0205/2971/
- 洛谷P1588 丢失的牛 https://www.luogu.org/problemnew/show/P1588
- 总时间限制: 2000ms 内存限制: 65536kB
- 描述
-
农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:
1、从X移动到X-1或X+1,每次移动花费一分钟2、从X移动到2*X,每次移动花费一分钟假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛? - 输入
- 两个整数,N和K
- 输出
- 一个整数,农夫抓到牛所要花费的最小分钟数
- 样例输入
-
5 17
- 样例输出
-
4
算法分析:
农夫在每个点都有三条路可以选择,即类似于:在每一个结点都有三个相邻的结点。现在需要最短时间找到牛,所以用广搜是比较容易解决的。关键是要理清楚数据结构的问题。
1 #include<stdio.h> 2 #include<queue> 3 #include<iostream> 4 using namespace std; 5 #define MAXINDEX 200010 6 //MAXINDEX的值达到K的2倍应该就可以了。但是在搜索过程中要注意不能越界。 7 int N,K; 8 int s[MAXINDEX]={0};//s[i]=t表示从出发点到达坐标i需要t分钟。 9 queue<int> q; 10 11 void BFS(); 12 int main(int argc, char *argv[]) 13 { 14 scanf("%d%d",&N,&K); 15 s[N]=1;//s[i]=0表示没有到达过坐标i这个地方。为了标记出起点,把s[N]设为1, 16 BFS(); 17 printf("%d\n",s[K]-1); //起点的步数是1,所以每个点的步数都多了1,应该减掉1. 18 return 0; 19 } 20 21 void BFS() 22 { 23 int i,nowIndex,newIndex; 24 if(N==K) return ; 25 26 q.push(N); 27 while(!q.empty()) 28 { 29 nowIndex=q.front(); 30 for(i=0;i<3;i++) 31 { 32 if(i==0) newIndex=nowIndex-1; 33 else if(i==1) newIndex=nowIndex+1; 34 else newIndex=nowIndex*2; 35 36 if(newIndex>=0&&newIndex<MAXINDEX&&s[newIndex]==0) 37 { 38 s[newIndex]=s[nowIndex]+1; 39 q.push(newIndex); 40 if(newIndex==K) return; 41 } 42 } 43 q.pop(); 44 } 45 }
时间复杂度约为log2(K/N)+x,其中x是2^t与K之差. (2^t是与K最接近的2的幂次值).
洛谷那道题的AC代码:

1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<queue> 5 using namespace std; 6 7 #define MAXINDEX 200010 8 //MAXINDEX的值达到K的2倍应该就可以了。但是在搜索过程中要注意不能越界。 9 int N,K; 10 int s[MAXINDEX]={0};//s[i]=t表示从出发点到达坐标i需要t分钟。 11 12 void BFS(); 13 int main() 14 { 15 int t; 16 scanf("%d",&t); 17 for(;t>0;--t) 18 { 19 scanf("%d%d",&N,&K); 20 s[N]=1;//s[i]=0表示没有到达过坐标i这个地方。为了标记出起点,把s[N]设为1, 21 BFS(); 22 printf("%d\n",s[K]-1); //起点的步数是1,所以每个点的步数都多了1,应该减掉1. 23 memset(s,0,sizeof(s)); 24 } 25 return 0; 26 } 27 28 void BFS() 29 { 30 int i,nowIndex,newIndex; 31 queue<int> q; 32 if(N==K) return ; 33 34 q.push(N); 35 while(!q.empty()) 36 { 37 nowIndex=q.front(); 38 for(i=0;i<3;i++) 39 { 40 if(i==0) newIndex=nowIndex-1; 41 else if(i==1) newIndex=nowIndex+1; 42 else newIndex=nowIndex*2; 43 44 if(newIndex>=0&&newIndex<MAXINDEX&&s[newIndex]==0) 45 { 46 s[newIndex]=s[nowIndex]+1; 47 q.push(newIndex); 48 if(newIndex==K) return; 49 } 50 } 51 q.pop(); 52 } 53 }
洛谷这道题的一个测试数据:
输入:
6
2880 39798
15051 67592
1860 27540
4560 24257
10696 86574
13746 47508
标准输出:
398
1849
144
1507
130
1871
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App