跳石板——网易校招
2017-02-22 20:57
274 查看
问题
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3…….这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
输入描述:
输入为一行,有两个整数N,M,以空格隔开。
(4 ≤ N ≤ 100000)
(N ≤ M ≤ 100000)
输出描述:
输出小易最少需要跳跃的步数,如果不能到达输出-1
解
动态规划问题。res[i]表示到i所花费的最小步数
当i+divisors[j]<=M时
res[i+divisors[j]]=min(res[i]+1,res[i+divisors[j]])
其中,divisors[j]为i的某个约数
#include<iostream> #include<vector> #include<math.h> using namespace std; void getDivisor(int n,vector<int>& divisors){ for(int i=2;i<=sqrt(n);i++){ if(n%i==0){ divisors.push_back(i); if(i*i!=n) divisors.push_back(n/i); } } } int soluation(int N,int M){ vector<int> res(M+1,999999);//初始化为一个大数表示不能达到 res = 1; for(int i=N;i<M;i++){ if(res[i]==999999) continue; vector<int> divisors; getDivisor(i,divisors); for(int j=0;j<divisors.size();j++){ if((i+divisors[j])<=M&&res[i]+1<res[i+divisors[j]]) res[i+divisors[j]] = res[i]+1; } } if(res[M]<999999) return res[M]-1; else return -1; }
相关文章推荐