minJump

题目

小易来到了一条石板路前,每块石板上从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

思路

循环i~[n,m], 得到i的约数集合*it
更新可以跳到的下一个点的最短的距离
要么保留,要么就是第i点+1
res[i+*it] = min(res[i+*it],res[i]+1);

注意

  1. 初始化的时候 和 最后结果输出 以及中间的 判断
    res[n]=1; //第一个设置为1,为了 if(res[i] == 0)这句话,启动,所以后面结果是res[m]-1
    if(res[i] == 0) continue;
  2. 每次更新的时候都必须判断 是否超出了m,否则数组越界
  3. 更新时还需判断是否为0,否则直接为res[i]+1

代码

#include<iostream>
#include<vector>
#include<set>
#include<math.h>
using namespace std;

// 得到n的约数,除了1和它本身
void get_yue_shu(int n, vector<int>&a){
    for(int i=2;i<=sqrt(n);i++){
        if(n%i==0){
            a.push_back(i);
            if(n/i != i)
                a.push_back(n/i);
        }
    }
}


void minJump(int n, int m)
{
    vector<int> res(m+1,0); //m+1 vector 0
    res[n]=1;  //第一个设置为1,为了 if(res[i] == 0)这句话,启动,所以后面结果是res[m]-1
    for(int i = n;i<=m;i++)
    {
        vector<int> a; //约数的集合
        get_yue_shu(i,a);
        if(res[i] == 0)
            continue;
        // iterator迭代器要用vector<int>::
        for(vector<int>::iterator it = a.begin();it!=a.end();it++)
        {
            if((i+*it)<=m&&res[i+*it]!=0)
                res[i+*it] = min(res[i+*it],res[i]+1);
            else if((i+*it)<=m)
                res[i+*it] = res[i]+1;
        }
    }
    if(res[m]==0)
        cout<<-1<<endl;
    else
        cout<<res[m]-1<<endl;
}

int main(){
    int n,m;
    cin>>n>>m;
    minJump(n,m);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值