codevs 3060 抓住那头奶牛
USACO
时间限制: 1 s
空间限制: 16000 KB
题目等级 : 黄金 Gold
题目描述 Description
农夫约翰被告知一头逃跑奶牛的位置,想要立即抓住它,他开始在数轴的N 点(0≤N≤100000),奶牛在同一个数轴的K 点(0≤K≤100000)。约翰有两种移动方式:1 分钟内从x 点移动到x+1 或x-1;1 分钟内从x 点移动到2x。假设奶牛不会移动,约翰抓住它需要多少时间?
输入描述 Input Description
一行两个整数N 和K,用空格隔开。
输出描述 Output Description
约翰抓住它需要的最少时间。
样例输入 Sample Input
5 17
样例输出 Sample Output
4
数据范围及提示 Data Size & Hint
见题目
1 /*借助这道题目再练习一下双向广搜*/ 2 #include<iostream> 3 using namespace std; 4 #define N 200100 5 #include<cstdio> 6 int visit[N]; 7 int dis[N]={0}; 8 #include<queue> 9 struct poi{ 10 int x,tim,flag; 11 }; 12 int n,k; 13 int bfs() 14 { 15 queue<poi>que; 16 visit[n]=1;visit[k]=2; 17 dis[n]=0;dis[k]=0; 18 que.push(poi{n,0,1}); 19 que.push(poi{k,0,2}); 20 while(!que.empty()) 21 { 22 poi now=que.front(); 23 que.pop(); 24 if(now.x-1>=0&&!visit[now.x-1]) 25 { 26 visit[now.x-1]=now.flag; 27 dis[now.x-1]=now.tim+1; 28 que.push(poi{now.x-1,now.tim+1,now.flag}); 29 } 30 else if(visit[now.x-1]&&now.flag!=visit[now.x-1]) 31 { 32 return dis[now.x-1]+1+now.tim; 33 } 34 if(now.x+1<=(N/2)&&!visit[now.x+1]) 35 { 36 visit[now.x+1]=now.flag; 37 dis[now.x+1]=now.tim+1; 38 que.push(poi{now.x+1,now.tim+1,now.flag}); 39 } 40 else if(visit[now.x+1]&&now.flag!=visit[now.x+1]) 41 { 42 return dis[now.x+1]+1+now.tim; 43 } 44 if(now.x*2<=(N/2)&&!visit[now.x*2]) 45 { 46 visit[now.x*2]=now.flag; 47 dis[now.x*2]=now.tim+1; 48 que.push(poi{now.x*2,now.tim+1,now.flag}); 49 } 50 else if(visit[now.x*2]&&now.flag!=visit[now.x*2]) 51 { 52 return dis[now.x*2]+1+now.tim; 53 } 54 } 55 } 56 int main() 57 { 58 scanf("%d%d",&n,&k); 59 cout<<bfs()<<endl; 60 return 0; 61 }