Hint: 此题可以看成是一颗三叉树进行层序遍历。如果把牛的坐标看成是不变的量,让农夫动,那么就会有三种情况:向左,向 右,还有除二操作。 注意用队列的时候要理解清楚谁进谁出
Accepted; 代码1.0版(整体的思路不是很清晰)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int vj[100100];
int main()
{
memset(vj,-1,sizeof(vj)); //用途有两个,第一是标记是否搜索过,第二记录走过的步数
int n, k, head, end;
int s[10010]; //队列数组
scanf("%d %d",&n,&k);
if(n > k) //分两种情况,农夫在牛的前面,和在后面
printf("%d\n",n-k);
else
{
head = 0;
end = 1;
s[0] = k;
vj[k] = 0;//表示已经走过了原始的k点,做标记
while(head < end)
{
if(s[head] == 0)
{
if(vj[s[head]-1] == -1)
{
s[end++] = s[head]-1;
vj[s[head]+1] = vj[s[head]]+1;//因为vj定义的是-1;所以要加一才能被标记
}
}
if(vj[s[head]+1] == -1)
{
s[end++] = s[head]+1;
vj[s[head]+1] = vj[s[head]]+1;
}
if(s[head]%2 == 0&&vj[s[head]/2] == -1)
{
s[end++] = s[head]/2;
vj[s[head]/2] = vj[s[head]]+1;
}
if(vj[n] != -1)
break;
head++;
}
printf("%d\n",vj[n]);
}
return 0;
}
Accepted; 代码2.0版(思路清晰)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int vj[100100], s[100100];
int head, end;
int main()
{
int n, k, g;
memset(vj,-1,sizeof(vj));
head = end = 0;
scanf("%d %d",&n,&k);
end++;
s[end] = k;
if(n >= k)
printf("%d\n",n-k);
else
{
vj[k] = 0;
while(head < end)
{
head++;
g = s[head];
if(vj[g+1] == -1)
{
vj[g+1] = vj[g]+1;
end++;
s[end] = g+1;
}
if(vj[g-1] == -1)
{
vj[g-1] = vj[g]+1;
end++;
s[end] = g-1;
}
if(g % 2==0&&vj[g/2] == -1)
{
vj[g/2] = vj[g]+1;
end++;
s[end] = g/2;
}
}
printf("%d\n",vj[n]);
}
return 0;
}