题目:
只含有数字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)个
3 用0表示4,1表示7
如:47表示为01,77表示为11
4 n位数中,最小的数min是4...4(总n个4)
5 将pos-1转换为二进制,将最小数min相应位按照“表示4,1表示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