抓住那头牛:
农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:
1、从X移动到X-1或X+1,每次移动花费一分钟
2、从X移动到2*X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?
Catch that cow:
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a pointN (0 ≤N ≤ 100,000) on a number line and the cow is at a pointK (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
* Walking: FJ can move from any pointX to the pointsX- 1 orX + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
以上是题目,具体输入输出如下:
输入
两个整数,N和K。
输出
一个整数,农夫抓到牛所要花费的最小分钟数。
这道题看似简单,实则有坑。简单的递归是不行的,要优先广度搜索。
要点:
1. 避免重复计算已通过节点,需要一个数组保存visited[]
2. 步数累积较简单,维护一个数组step[],子节点为父节点+1
3. 将子节点压入队列的之前就应该检查是否visited
4. 越界处理,不能为负数或者太大越界
两种方法,第一种更简单明了
package 序列找数;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class catch_cow {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(solu2(5,17));
}
public static int solu(int n, int k){
if(n==k) return 0;
int max = 10000000;
//一个放接下来的数的队列
LinkedList<Integer> list = new LinkedList<Integer>();
int[] visited = new int[max];
int[] step = new int[max];
list.add(n);
step[n]=0;
int chid=0;
while(!list.isEmpty()){
int father = list.removeFirst();
for(int i =0;i<3;i++){
if(i==0) chid=father+1;
if(i==1) chid=father-1;
if(i==2) chid=father*2;
if(chid<0||chid>max) continue;
if(visited[chid]==0){
visited[chid]=1;
list.add(chid);
step[chid]=step[father]+1;
}
if(chid == k) return step[chid];
}
}
return -1;
}
public static int solu2(int n, int k){
if(n==k) return 0;
int max = 10000000;
//一个放接下来的数的队列
LinkedList<Integer> list = new LinkedList<Integer>();
int[] visited = new int[max];
int[] step = new int[max];
list.add(n);
step[n]=0;
visited[n]=1;
int chid=0;
while(!list.isEmpty()){
int father = list.removeFirst();
//step[father]=
if(father==k) return step[father];
if(father<0||father>max) continue;
//visited[father]=1;
if(visited[father+1]==0){
visited[father+1]=1;
step[father+1]=step[father]+1;
list.add(father+1);
}
if(father>0&&visited[father-1]==0){
visited[father-1]=1;
step[father-1]=step[father]+1;
list.add(father-1);
}
if(visited[father*2]==0){
visited[father*2]=1;
step[father*2]=step[father]+1;
list.add(father*2);
}
}return -1;
}
}