首页 > 试题广场 >

求x到y的最少计算次数

[编程题]求x到y的最少计算次数
  • 热度指数:3221 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定两个-100到100的整数x和y,对x只能进行加1,减1,乘2操作,问最少对x进行几次操作能得到y?
例如:
a=3,b=11: 可以通过3*2*2-1,3次操作得到11;
a=5,b=8:可以通过(5-1)*2,2次操作得到8;


输入描述:
输入以英文逗号分隔的两个数字,数字均在32位整数范围内。


输出描述:
输出一个数字
示例1

输入

3,11

输出

3
import java.util.*;

public class Main {
    
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String[] nums = s.split(",");
        int a = Integer.parseInt(nums[0]);
        int b = Integer.parseInt(nums[1]);
        
        int ans = solution(a,b);
        System.out.println(ans);
    }
    
    private static int solution(int a, int b){
        
        int ans = 0;
        // 特殊值
            if(a == 0 && b <= 0) return Math.abs(b);
            if(a == 0 && b > 0) return minOps(1,b) + 1;

        // a b 同号
        if(a * b > 0){
            a = Math.abs(a); b = Math.abs(b);
            if(a >= b) return a - b;
            // a < b
            else return minOps(a,b);
        } 
        // a b 异号
        // 如果 a 是负值,将 a 转换为正值 1,则 a * b > 0,调用自身得到结果。
        if(a < 0) return ans - a + 1 + solution(1,b);
        // 如果 b 是负值,将 b 转换为正值 1。
        return ans - b + 1 + solution(a,1);
    }
    
    private static int minOps(int a, int b){

        if(b >= a && b <= (a << 1))
            return Math.min(b - a,(a << 1) - b + 1);
        if((b & 1) == 1)
            return Math.min(minOps(a,(b + 1) >> 1), minOps(a,(b - 1) >> 1)) + 2;
        return minOps(a,b >> 1) + 1;
    }
}

编辑于 2020-07-12 15:46:38 回复(0)
深度优先搜索
import java.util.Scanner;

/**
 * @Author: coderjjp
 * @Date: 2020-05-09 18:27
 * @Description:
 * @version: 1.0
 */
public class Main {
    static Scanner sc = new Scanner(System.in);
    static String s[] = sc.next().split(",");
    static int x = Integer.valueOf(s[0]);
    static int y = Integer.valueOf(s[1]);
    static int min = Math.abs(x - y);//最小值的上界
    public static void main(String[] args) {
        dfs(x, y, 0);
        System.out.println(min);
    }

    private static void dfs(int x, int y, int count) {
        if (count == min)
            return;
        if (x == y){
            min = count;
            return;
        }
        dfs(x + 1, y, count + 1);
        dfs(x - 1, y, count + 1);
        dfs(x * 2, y, count + 1);
    }
}

发表于 2020-05-09 19:48:34 回复(1)
import java.util.Scanner;

public class Main {
//思路:从Y逆推,如果Y是奇数就减一(或加一,两种情况比较哪个次数少);之后让Y不断除以2,如果能变成X,就结束
    //不能则在比X小的时候停下来(如果比他它大1,偶尔也要让-1发挥一下,就停止),计算要+1多少次
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
String line = sc.nextLine();
String[] split = line.split(",");
int x=Integer.valueOf(split[0]);
int y=Integer.valueOf(split[1]);
int res ;
if(x<y&&x>0)//负数这里测试用例,只需要把它当做只能靠x+1来变化
res = Math.min(xToy(x,y,-1),xToy(x, y, 1));
else
res=Math.abs(x-y);
System.out.println(res);
}
sc.close();
}
private static int xToy(int x, int y,int plus) {
int count=0;
if(y%2!=0) {
y=y+plus;
count++;
}
while(y>x) {
y=y/2;//要整除,不整除向下取整
count++;
if(y-1==x){return count+1;}
}
count+=x-y;//x-y是当y小于x的时候,两者的差值
return count;
}
}
编辑于 2019-09-10 10:34:00 回复(1)