第k个幸运数字

题目:
只含有数字4和7的数字为幸运数字。如:4 7 44 47 74 77…
输入第一行表示输入的组数T,接下来的T行表示第几个幸运数字,输出为T行,表示这T个幸运数字。
例如:
输入:
3
1
3
5
输出:
4
44
74

思路:

准备:
 1 n位数中,有2^n个幸运数
  如:1位数中,有2^1=2个幸运数,即4 7
      2位树中,有2^2=4个幸运数,即44 47 74 77
 2 2^1+2^2+...+2^n=2*(2^n-1)
思路:
 1 求第k个幸运数字,应该先求出该数字有多少位
      2*(2^n-1)=k ==> 最多有n=log2(k/2+1)位
 2 求出该数字是n位数中的第几个
      位数小于n的幸运数共有2^1+2^2+...+2^(n-1)=2*(2^(n-1)-1)个
     所以所求幸运数是n位数中的:第pos=k-2*(2^(n-1)-1)个
 30表示41表示7
      如:47表示为0177表示为11
 4 n位数中,最小的数min是4...4(总n个45 将pos-1转换为二进制,将最小数min相应位按照“表示41表示7”的规则表示,即为最终结果

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class LuckNum {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()){
            int T = scanner.nextInt();
            List<String> list = new ArrayList<String>();
            for(int i=0;i<T;i++){
                list.add(outLuckNum(scanner.nextInt()));
            }
            for(int i=0;i<T;i++){
                System.out.println(list.get(i));
            }
        }
    }
    public static String outLuckNum(int k){
        //第k个幸运数的位数
        int d = (int)Math.ceil(Math.log(k+2) / Math.log(2)-1);
        //第k个幸运数是d位数中的第几个
        int pos = (int)(k-2*(Math.pow(2,d-1)-1));
        String bNum = Integer.toBinaryString(pos-1);
        //让转换后的二进制数的位数等于该幸运数的位数
        String zeros = "";
        for(int i=1;i<=d-bNum.length();i++){
            zeros += "0";
        }
        bNum = zeros+bNum;
        //按照规则“表示4,1表示7”,将转换后的二进制数转换为幸运数
        String num = "";
        for(int i=0;i<bNum.length();i++){
            if(bNum.charAt(i)=='1'){
                num += '7';
            }else {
                num += '4';
            }
        }
        return num;
    }
}

测试:

输入:
5
5
7
9
10
15
输出:
74
444
474
477
4444
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值