列表

详情


QQ8. 数字转换机

描述


小Q从牛博士那里获得了一个数字转换机,这台数字转换机必须同时输入两个正数a和b,并且这台数字转换机有一个红色的按钮和一个蓝色的按钮:

当按下了红色按钮,两个数字同时加1。

当按下了蓝色按钮,两个数字同时乘2。

小Q现在手中有四个整数a,b,A,B,他希望将输入的两个整数a和b变成A,B(a对应A,b对应B)。因为牛博士允许小Q使用数字转换机的时间有限,所以小Q希望按动按钮的次数越少越好。请你帮帮小Q吧。




输入描述

输入包括一行,一行中有四个正整数a,b,A,B,(1≤a,b,A,B≤10^9)。

输出描述

如果小Q可以完成转换,输出最少需要按动按钮的次数,否则输出-1。

示例1

输入:

100 1000 202 2002

输出:

2

原站题解

C++14 解法, 执行用时: 2ms, 内存消耗: 344KB, 提交时间: 2019-04-07

#include<stdio.h>
int Minimum = 999999;
int dfs(int a,int b,int A,int B,int step){
    if(a>A || b>B){
        return -1;
    }
    if(step>Minimum){
        return -1;
    }
    if((A==a && b!=B )||(B==b && a!=A)){
        return -1;
    }
    if(a==A && b==B){
        if(step<Minimum && step>=0){
            Minimum = step;
        }
    }
    dfs(a*2,b*2,A,B,step+1);
    dfs(a+1,b+1,A,B,step+1);
    return -1;
}
int main(){
    int a,b,A,B;
    scanf("%d%d%d%d",&a,&b,&A,&B);
    int res = dfs(a,b,A,B,0);
    if(Minimum!=999999){
        printf("%d\n",Minimum);
    }else{
        printf("-1\n");
    }
    return 0;
}

Rust 解法, 执行用时: 3ms, 内存消耗: 328KB, 提交时间: 2020-08-16

use std::str::FromStr;

fn min_times(a: usize, b: usize, A: usize, B: usize, times: usize) -> (bool, usize) {
    if a > A || b > B {
        (false, times)
    } else if a == A && b == B {
        (true, times)
    } else {
        let (is_success, times1) = min_times(a + 1, b + 1, A, B, times);
        if is_success {
            (true, times1 + 1)
        } else {
            let (is_success, times2) = min_times(a * 2, b * 2, A, B, times);
            (is_success, times2 + 1)
        }
    }
}

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_line(&mut buf);
    let mut nums = buf.trim_end().split(' ').map(usize::from_str).flatten();
    let (a, b, A, B) = (
        nums.next().unwrap(),
        nums.next().unwrap(),
        nums.next().unwrap(),
        nums.next().unwrap(),
    );
    let (is_success, times) = min_times(a,b,A,B,0);
    if is_success {
        println!("{}", times);
    }else{
        println!("-1");
    }
}

C 解法, 执行用时: 3ms, 内存消耗: 352KB, 提交时间: 2022-07-29

#include<stdio.h>
#include<stdlib.h>
int main() {
    int a=0,b=0,A=0,B=0,i=1,p=1,fnum,lnum,aa=0;
	scanf("%d%d%d%d",&a,&b,&A,&B);
	if(A<a||B<b){
        printf("-1");
        }
    else{
        while(i++){
            if(aa<0){
            printf("-1");
            break;
            }
            if(aa==B-b*p/2){
            fnum=i-3;
            break;
            }
            aa=A-a*p;
            p=p*2;
        }
        if(aa!=0){
            for(i=0,lnum=0;aa!=0;i++){
                if(aa%2==0&&lnum<fnum){
                    aa=aa/2;
                    lnum++;
                }
                else{
                    aa--;
                }
            }
            printf("%d\n",i);
        }
        else{
            printf("%d\n",fnum);
        }
    }
    return 0;
}

C 解法, 执行用时: 3ms, 内存消耗: 384KB, 提交时间: 2020-07-05

#include <stdio.h>
#include <stdlib.h>

int min(int a,int b)
{
	if(a==-1&&b==-1)
		return -1;
	if(a==-1&&b!=-1)
		return b;
	if(b==-1&&a!=-1)
		return a;

	return a>b?b:a;
}
int dfs(int a,int b,int A,int B,int nums)
{
	if(a>A||b>B)
		return -1;
	if(a==A&&b==B)
	{
		return nums;
	}
	else
	{
		nums++;
//		;
//		;
		return min(dfs(a+1,b+1,A,B,nums),dfs(a*2,b*2,A,B,nums));
	}
}

int main(void) {
	int a,b,A,B;
	scanf("%d %d %d %d",&a,&b,&A,&B);
//	a=100;
//	b=1000;
//	A=202;
//	B=2002;
	printf("%d",dfs(a,b,A,B,0));
}

C++ 解法, 执行用时: 3ms, 内存消耗: 404KB, 提交时间: 2022-06-13

#include <vector>
#include <iostream>
#include <limits.h>
using namespace std;
int trans( int a, int b,  int A,  int B, vector<vector<int>> &dp){
    if(A>=a && B>=b && dp[A-a][B-b] != INT32_MAX) return dp[A-a][B-b];
     int ret = INT32_MAX;
    if(a == A && b == B) return 0;
    if(a > A && b >B) return -1;
    if( A % 2 == 0 && B % 2 ==0){
         int ret1 = trans(a, b, A - 1, B - 1, dp);
        if(ret1 != -1) {
            if(A > a && B> b) dp[A-1-a][B-1-b] = ret1;
            ret = min(ret, ret1 + 1);

        }
        int ret2 = trans(a, b, A / 2, B / 2, dp);
        if(ret2 != -1){
            if(A/2 >= a && B/2 >= b) dp[A/2-a][B/2-b] = ret2;
            ret = min(ret, ret2 + 1);
        } 
    }else{
        int ret3 = trans(a, b, A - 1, B-1, dp) ;
        if(ret3 != -1) {
            if(A > a && B> b) dp[A-1-a][B-1-b] = ret3;
            ret = min(ret, ret3 + 1);
        }
    }
    if(ret == INT32_MAX) ret = -1;
    if(A>=a && B>=b) dp[A-a][B-b] = ret;
    return ret;
}
int main(){
     int a,b,A,B;
    while(cin >> a >> b >> A >> B){
        if(A-a<0 || B-b<0){
            cout << -1 << endl;
            continue;
        }
        vector<vector<int>> dp(A+1 - a, vector<int>(B+1 - b, INT32_MAX));
        cout << trans(a, b, A, B, dp) << endl;
    }
    return 0;
}

上一题