腾讯9月13号数字转换机的题解,大家帮忙看看对不对。

【题目】
大意就是现在给a b A B 四个整数,每次可以对a b同时做一个+1操作或一个*2操作,问经过多少次操作之后a转化为A,同时b转为B。求操作的最小次数,如果不能转换就输出-1。
【思路】
其实首先可以进行一个公式转换。
假设总共进行了n次*2操作, m次+1操作,第i次+1操作后面进行了ki次*2操作。那么:
A = a*2n + 2k1 + … + 2km
B = b*2n + 2k1 + … + 2km, 其中,n >= k1 >= k2 >= … >= km >= 0
例如,假设a=101,
((a+1+1)*2+1)*2+1 =((101 + 1 + 1)*2 +1)*2 + 1 = 101 * 2 * 2 + 1 * 2 * 2 + 1 * 2 *2 + 1 * 2 + 1 = a * 22+22+22+21+20
n=2, m=4, k1=2, k2=2, k3=1, k4=0
有了这个公式就好办了,只需要枚举n的值,然后判断 A - a*2n == B - b*2n ,再计算m的值即可。
#include<iostream>
#include<cmath>
#include<climits>
using namespace std;

int calculateM(int remain, int n)
{
    int m = 0;
    do
    {
        m += remain / (1 << n);
        remain = remain % (1 << n);
        n--;
    }while(n >= 0 && remain > 0);
    return m;
}
int findMin(int a, int b, int A, int B)
{
    int maxMulti = min((int)(log(((double)A)/a)/log(2.0)),(int)(log(((double)B)/b)/log(2.0)));
    int min = INT_MAX;
    for(int n = maxMulti; n >= 0; --n)
    {
        if(A - (a << n) == B - (b << n))
        {
            int m = calculateM(A - (a << n), n);
            min = m + n < min ? m + n : min;
        }
    }
    if(min == INT_MAX)
        return -1;
    return min;
}

int main()
{
    int a, b, A, B;
    cin >> a >> b >> A >> B;
    cout << findMin(a,b,A,B) << endl;
    return 0;
}



#腾讯#
全部评论
楼主大佬,成功的让我发现我笔试时候做错了。。。
点赞 回复 分享
发布于 2017-09-15 18:54

相关推荐

05-28 23:26
河南大学 Java
双非本,刚学完Redis,项目只有外卖和点评,八股没准备,算法只有lqb省一,感觉敲的项目也是一言难尽没怎么吸收。怎么你们都有实习了
大牛之途:27急个锤子,你投日常实习最好的时间就是9,10月份,那时候暑期实习都结束了,正是缺人的时候。这份日常又能给你的暑期实习增加竞争力,暑期找的好了秋招也不怕了,都是环环相扣的
点赞 评论 收藏
分享
04-25 18:13
五邑大学 Java
后来123321:大二两段实习太厉害了,我现在大二连面试都没有
点赞 评论 收藏
分享
关于我大学本科四年,想了很多,但还是不知道该怎么动笔&nbsp;“大学四年,是我从懵懂少年走向职场青年的转折期。这一路跌跌撞撞,有迷茫,有遗憾,也有成长和决心。”&nbsp;大一刚进来时仍然有高中那股学习劲,经常一个人去图书馆学高等数学,但后面劲头一过便开始在宿舍开启躺平生活(现在想想那段时间真的很爽,无忧无虑)。由于大一担任班干部,所以经常要跟其他班的班干部交流,在此期间认识了隔壁班的一位女生,短发而很可爱,因为很多团建还有比赛都是我们两班一起参加的,而且我和她都是负责人,所以交集很多,后面慢慢地彼此对产生了好感,所以在大一刚开学的2个月后,我们在一起了,彼此之前都是初恋。但当时我真的是太太太直男了,对感情的想...
真烦好烦真烦:骗哥们可以,别把你自己也骗到了就行。哥们被你骗了真无所谓的,打个哈哈就过了。但希望你打完这段话后擦一下眼角,别让眼泪掉在手机屏幕上了就行。你说的这些话,哥们信一下也是没什么的。还能让你有个心里安慰,但这种话说出来骗骗兄弟就差不多得了,哥们信你一下也不会少块肉,但是你别搞得自己也当真了就行。哥们被你骗一下是真无所谓的,兄弟笑笑也就过去了。真不是哥们想要破你防,你擦擦眼泪好好想想,除了兄弟谁还会信你这些话?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务