魔法币问题

注:此题原题来源于牛客网,网易2018校园招聘编程题

问题描述:

小易准备去魔法王国采购魔法神器,购买魔法神器需要使用魔法币,但是小易现在一枚魔法币都没有,但是小易有两台魔法机器可以通过投入x(x可以为0)个魔法币产生更多的魔法币。
魔法机器1:如果投入x个魔法币,魔法机器会将其变为2x+1个魔法币
魔法机器2:如果投入x个魔法币,魔法机器会将其变为2x+2个魔法币
小易采购魔法神器总共需要n个魔法币,所以小易只能通过两台魔法机器产生恰好n个魔法币,小易需要你帮他设计一个投入方案使他最后恰好拥有n个魔法币。

链接:https://www.nowcoder.com/questionTerminal/32c71b52db52424c89a565e4134bfe4e
来源:牛客网

输入描述:
输入包括一行,包括一个正整数n(1 ≤ n ≤ 10^9),表示小易需要的魔法币数量。


输出描述:
输出一个字符串,每个字符表示该次小易选取投入的魔法机器。其中只包含字符'1'和'2'。
示例1

输入

10

输出

122

此题的关键在于2x + 1和2x + 2

前者为奇数,后者为偶数。也就是说如果结果为奇数,那么他上一次使用的机器必定为一号机,同理,如果最后结果是偶数,那么他上一次使用的机器就是二号机。

例如,这里的最终结果为10,那么我就可以反推回去,上一个是用的二号机,2x + 2 = 10 解得 x = 4, 继续反推 2x + 2 = 4 解得 x = 1,

  最后 2x + 1 = 1 解得 x = 0。而最开始的魔法币即为10,推算完成。上代码

package algorithms;


import java.util.Scanner;


public class MagicCOINS{
public static void main(String[] args){
System.out.print("请输入你要制造的魔法币数量:");
Scanner input = new Scanner(System.in);
int test = input.nextInt();
System.out.println("请按如下顺序使用魔法机:" + solution(test));
}

/**
* 传递魔法币数量,返回使用魔法机器的顺序,1代表使用一号魔法机,2代表使用二号魔法机
* @param num
* @return
*/
public static String solution(int num){
String result = "";
while(num != 0){
if(num % 2 == 0){//如果这个数是偶数,就说明它是通过二号魔法机器产生的
num = (num - 2)/2;//回溯回去,查看上一个数
result = 2 + result;//注意,这里不能使用result += 2;这样会导致最终的结果字符串与预想的相反
}else{
num = (num - 1)/2;
result = 1 + result;
}
}
return result;
}
}

使用String的话,在每次 + 运算时都要new一个新的String对象,如果数据庞大,推荐使用StringBuilder


除此之外,我还想出一个利用树的算法,本人笨拙,算法可能不是很好


继续将此树画下去,即可发现,这就是一颗编码树

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值