”牛客网“跳石板
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
/*
* 超级变态跳台阶
* 从台阶m到台阶n,每步只能跳当前台阶的因数(除了1和其本身),求跳到台阶m需要的最小步数
* 使用mark[i]数组记录从台阶m跳到台阶i需要的最小步数
* 初始时:只有mark[m]为0,其余为正无穷
* 对于每一个i~[m,n-2],计算得到其因数temp,if(i+temp<=n)执行以下步骤:
* 若mark[i+temp]>mark[i]+1,那么更新mark[i+temp]为mark[i]+1
*
* 到i=n-2时,只有temp=2满足条件,直接跳到台阶n。因此不需要再遍历i=n-1以及i=n
* 最终得到的mark[n]即所求结果
*
* 进阶:
* 打印出跳的路径
* 新增一个数组,保存跳到该台阶经过的上一级台阶
*/
public class JumpSlate {
private static int[] mark;
private static int[] path;
static int start;
static int dest;
public static void JumpSlate(){
Scanner sc = new Scanner(System.in);
int startSlate = sc.nextInt(); //起始台阶
int destSlate = sc.nextInt(); //目标台阶
start = startSlate;
dest = destSlate;
//给mark数组分配空间
mark = new int[destSlate+1]; //记录到达每一个位置的最小步数
path = new int[destSlate+1]; //记录到达当前台阶所经过的上一级台阶编号
//初始化每一个值为正无穷,得到最终结果时仍保留为正无穷的台阶即为不可达
for(int i=startSlate+1;i<=destSlate;i++){
mark[i] = Integer.MAX_VALUE;
path[i] = Integer.MAX_VALUE;
}
//设置初始台阶需要的步数为0
mark[startSlate] = 0;
path[startSlate] = startSlate;
//遍历mark数组,对每一个台阶所需步数进行计算
//i~[startSlate,destSlate-2]
for(int i=startSlate;i<=destSlate-2;i++){
ArrayList<Integer> factorList = calFactors(i);
//对于跳j阶可以到达的台阶进行更新
for(int j=0;j<factorList.size();j++){
int thisStep = factorList.get(j);
int toSlate = i+thisStep; //跳thisStep阶之后,可以从台阶i跳到台阶toSlate
if(toSlate<=destSlate) //检查跳thisStep之后是否超出界限
{
if(mark[toSlate]>mark[i]+1 && mark[i]!=Integer.MAX_VALUE) //如果toSlate台阶中保存的步数大于当前经过台阶i所需的步数
{
//更新mark[toSlate]中的值
//即更新到达toSlate的方式为经过i到达
mark[toSlate] = mark[i]+1;
path[toSlate] = i;
}
}
else{
continue;
}
}
}
int result = mark[destSlate];
if(result==Integer.MAX_VALUE)
result = -1;
System.out.println("need step:"+result);
}
/*
* 计算因数,返回ArrayList类型因数列表
*/
private static ArrayList<Integer> calFactors(int num){
ArrayList<Integer> factors = new ArrayList<Integer>();
for(int i=2;i<=Math.sqrt(num);i++){
if(num%i==0){
factors.add(i);
if(i!=num/i) factors.add(num/i);
}
}
return factors;
}
public static void printPath(){
if(path[dest]!=Integer.MAX_VALUE){ //如果当前目的地是可达的
Stack<Integer> records = new Stack<>();
int lastSlate = path[dest];
while(lastSlate!=start){
records.push(lastSlate);
lastSlate = path[lastSlate];
}
System.out.print("path:");
System.out.print(start+"->");
while(!records.isEmpty())
{
System.out.print(records.pop()+"->");
}
System.out.println(dest);
}
}
}
解题思路参照 图论最短路径算法