21天学习挑战赛--猜密码

活动地址:CSDN21天学习挑战赛

题目描述

小杨申请了一个保险柜,但是忘记了密码。只记得密码都是数字,而且数字都是不重复的。请根据数字范围和密码的最小数字数量,计算所有可能的密码组合,规则如下:

  • 输出的组合都是从可选的数字范围中选取的,且不能重复;
  • 输出的密码数字要按照从小到大的顺序排列,密码组合需要按照字典顺序,从小到大的顺序排序;
  • 输出的每一个组合的数字的数量要大于等于密码最小数字数量;
  • 如果可能的组合为空,则返回“None”。

输入描述

输入的第一行是可能的密码数字列表,数字间以半角逗号分隔;

输入的第二行是密码最小数字数量。

输出描述

可能的密码组合,每种组合显示成一行,每个组合内部的数字以半角逗号分隔,从小到大的顺序排列。输出的组合间需要按照字典顺序排列。

示例

输入

2,3,4

2

输出

2,3

2,3,4

2,4

3,4

思考

原博主 给出的解题思路如下:

1、因为密码是升序的,所以首先要对输入的数字进行升序排序。

2、根据题意是从可选的密码数字列表中选出对应的数量的数字作为密码。也就是从M个字符中取出N个字符的全排列(经典算法)

3、因为最小数字数量是N,所以需要一直遍历到可选密码数字列表的长度,才能得到所以可能的密码组合。

我的思考

题目的意思是从给定的M个数字中取出长度在[N,M]区间内的所有数字组合,并将得到的数字组合按照字典顺序排序。

中间较复杂的问题就是取长度在[N,M]变化的数字组合,简化一下就是取定长L的数字组合,这样就简单多了。

代码实现

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] strings = sc.nextLine().split(",");
        int n = sc.nextInt();
        
        //对输入数字进行升序排序
        Arrays.sort(strings);
        //存放数字组合结果
        List<String> list = new ArrayList<>();
        //数组长度l在区间[N,M]间移动
        for(int l=n;i<=strings.length;l++) {
            combine(list,strings,i,new String(),0);
        }
        //将数字组合排序
        Collections.sort(list);
        if(list.size() == 0) {
            System.out.println("None");
        }else {
            list.stream().
                forEach(System.out::println);
        }
    }
  
    public static void combine(List<String> list, String[] str, int n, String res, int index) {
        //list  存储数字组合的结果
        //str  排序后的输入数字组合
        //n  数字组合的长度
        //res  数字组合的字符串
        //index  开始循环的下标
        if(n == 0) {
            //一个数字组合拼接完毕,放入存储
            list.add(res);
        }else{
            //从index处开始循环,一个个拼接
            for(int i=index;i<str.length;i++) {
                //拼接
                if(index == 0)
                	res += str[i];
                else
                    res += "," + str[i];
                //进入下一个分支
                combine(list,str,n-1,res,i+1);
                //将刚刚拼接的最后一个数字剔除
                if(index == 0) {
                	res = res.substring(0, res.length()-1);
                }else {
                    res = res.substring(0,res.length() - - 2);
                }
            }
        }
    }
}

我的理解和收获

本题目中最复杂的部分就是从长度为M的数字中取长度为L的数字组合,这其实很像分治。

比如从1,2,3,4中取两个数字:

先取1,在【2,3,4】中取剩下的一个,有三种;

然后取2,在【3,4】中取剩下的一个,有两种;

然后取3,在【4】中取剩下的一个,有一种;

或者1,2,3,4中取三个数字:

先取1,在【2,3,4】中取剩下的两个:

先取2,在【3,4】中取剩下的一个,有两种;

然后取3,在【4】中取剩下的一个,有一种。

所以这里有三种情况;

然后取2,在【3,4】中取剩下的两个:

先取3,然后在【4】中取剩下的一个,有一种;

所以这里有一种情况。

加一起有四种情况

推广一下就是

从M个字符中取L个字符:

先取一个,在剩下的M-1个字符中取L-1个字符:

先取一个,在剩下的M-2个字符中取L-2个字符:

总结一下,就是切割字符,然后从剩下的字符中取字符。

2023年Mathorcup大数据挑战赛赛道A将是一场激动人心的竞赛。本次比赛旨在鼓励参赛者运用大数据技术解决实际问题,并推动数据科学在各行各业的应用。以下是我对这个比赛赛道的一些见解: 首先,比赛赛道A将关注某个特定领域的大数据分析,可能是金融、医疗、物流等等。参赛者需要运用数据挖掘、机器学习等技术,对相关数据集进行分析和建模,以解决特定领域内的难题。 其次,参赛者需要具备良好的数据分析能力和工程实践经验。他们可能需要处理大规模的数据集,进行数据清洗、特征提取和模型构建等工作。同时,他们还需要选取合适的算法和模型,并通过实验和优化来提高模型的准确性和效率。 此外,比赛要求参赛者具备良好的团队合作和沟通能力。因为在实际项目中,数据科学家往往需要与数据工程师、业务团队等进行紧密合作,共同解决问题。因此,团队之间的协作和交流能力将成为获胜的关键因素之一。 最后,本次比赛的评分标准很可能是多样化的。除了数据分析的准确性和效果外,评审团可能还会考虑参赛者的创新性、算法设计的合理性、代码的规范性等。因此,参赛者需要在综合能力上有所准备,不仅要关注具体问题的解决,还要注重整体方案的优化和优化思路的创新。 总而言之,2023年的Mathorcup大数据挑战赛赛道A将是一场对数据科学者们来说难得的机会。通过这次比赛,参赛者将不仅可以提升自己的数据分析技能,还可以结识更多的行业专家和同行,并为实际问题的解决贡献自己的力量。希望这场比赛能够激发更多人对大数据挖掘和应用的热情,推动科技的进步和社会的发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值