哈哈,还记得老师说过所有关于奶牛的poj题都是一个团队写的,
不说多了切入主题,这道题其实也是博主第一次接触bfs算法(广度优先遍历)相应维基百科链接http://zh.wikipedia.org/wiki/%E5%B9%BF%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2,所以借鉴了很多过来人的程序哈;
这道题题意是
输入人的位置坐标N,和奶牛的位置坐标K,已知人从自己的位置N移动到N-1,N+1,2*N的位置所用的时间均为一分钟,输出人到达奶牛的所需最短的时间(奶牛是不移动的);
这道题恰好体现了广搜bfs算法的经典用途,求最短路径;思路如下
人可能移动的坐标会组成一个树结构,根据队列queue有先进先出的特点,所以可以用队列存储每个结点及其下一个分支;给用一个足够大的数组存储到达每个节点的步数,另用一个数组来标识遍历到的位置,并同时遍历步数相同的每个结点,若到达了目的K,则此时的步数即是最短的步数,若还未到达目的地K,则继续遍历该节点的分支的结点;听起来会比较抽象,由于博主能力有限所以时间复杂性没算出来,嘿嘿,具体看程序如何实现;
#include<iostream>
using namespace std;
#include<queue>
#define maxn 100001
queue<int>cow; //申请一个全局的队列cow
int step[maxn]; //存储到达遍历的结点所需的步数
int visit[maxn]; //标记每个已被遍历的结点,防止该结点再被操作
int check(int n,int k);
int main()
{
int n,k,most;
cin>>n>>k;
most=check(n,k);
cout<<most<<endl;
return 0;
}
int check(int n,int k)
{
int head,next,i;
if(n>=k)return n-k; //如果n大于k则人只能通过位置减一到达奶牛处
cow.push(n);
step[n]=0;
visit[n]=1;
while(!cow.empty())
{
head=cow.front();
cow.pop();
for(i=1;i<=3;i++) //三种可能
{
if(i==1) next=head-1;
else if(i==2) next=head+1;
else next=2*head;
if(next<0||next>maxn) continue; // 判断是否越界
if(!visit[next])
{
step[next]=step[head]+1;
visit[next]=1; //表示第next已被访问
cow.push(next);
}
if(next==k)return step[next]; //已到达目的地K处,返回最短步数
}
}
return 0;
}