第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
### 蓝桥杯 幸运数字 题目 解题思路 #### 一、题目背景 幸运数是由波兰数学家乌拉姆命名的一种特殊整数序列,其生成方法类似于素数的埃拉托斯特尼筛法。通过不断筛选掉特定位置上的数字来逐步构建整个序列[^3]。 #### 二、核心概念解析 1. **定义理解** 幸运数是一个按照一定规则逐层剔除后的剩余自然数组成的集合。初始列表由正奇数构成(即`1, 3, 5, 7...`),随后依据当前幸存项的位置依次删除对应倍率下的其他成员直到无法再继续操作为止。 2. **算法设计原则** - 利用数组或者链表存储候选数值; - 循环迭代过程中动态调整保留下来的下标范围; - 借助布尔型标记变量辅助记录哪些索引已被移除从而避免重复计算浪费性能开销。 #### 三、具体实现方式 以下是基于 Java 的解决方案展示: ```java import java.util.ArrayList; import java.util.List; public class LuckyNumber { public static void main(String[] args){ int n = 100; // 设定寻找前n个幸运数 List<Integer> numbers=new ArrayList<>(); for(int i=1;i<=2*n;i+=2){ numbers.add(i); } int step=1; while(numbers.size()>step){ int count=0; for(int index=numbers.size()-1;index>=0;--index){ ++count; if(count%step==0 && !(count/step<step)){ numbers.remove(index); } } step++; } System.out.println("The first "+n+" lucky numbers are:"); for(Integer num : numbers.subList(0,n)){ System.out.print(num+", "); } } } ``` 上述代码片段实现了基本的功能需——找出指定数量内的所有幸运数并打印出来。值得注意的是,在实际应用当中可能还需要考虑边界条件以及效率优化等问题。 另外一种更为高效的解决办法则是利用质因数分解特性直接枚举满足条件的结果集而不必经历繁琐的过滤过程。例如下面这个 Python 版本的例子就采用了这种方法快速统计小于某个极值的所有符合条件的幸运数总共有多少个实例存在[^4]: ```python cnt=0 for i in range(50): for j in range(50): for k in range(50): if (3**i)*(5**j)*(7**k)<=59084709587505: cnt+=1 print(cnt) ``` 此脚本通过三层嵌套循环遍历所有可能组合形式进而得出最终答案。尽管看上去简单粗暴但却非常有效尤其当目标上限非常高难以逐一验证每一个单独情况的时候显得尤为实用。 #### 四、总结说明 无论是采取经典的模拟筛选流程还是巧妙运用数学规律简化运算逻辑都能成功解答关于蓝桥杯竞赛中的“幸运数字”相关命题只是各自适用场景有所不同而已。前者更贴近原始定义易于理解推广后者则侧重技巧性实战效能适合处理规模数据情形之下追极致速度的情形之中[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值