蓝桥杯决赛javaA组--凑平方数

题目描述


凑平方数

把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721

再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等…

注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。

如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?

注意:需要提交的是一个整数,不要填写多余内容。


解题思想


/*
首先要明白的一个问题,就是0--9十个数,如何判断一种满足题意的情况,组合完成?
我的想法就是用一个index来跟踪当前枚举的是第几位。
这道题肯定要用dfs,因此递归结束的条件就可以写成index==10
直接说dfs(i,j)表示枚举的一种满足题意的十位数中的第i位,枚举到第j的平方,所代表的数
比如1,25,6390784这种情况
当枚举到j=1,的时候,满足条件,此时i=1,
然后当枚举到j=5,此时为25,i=3,。。
就是这样。
但是这要解决个问题,首先j的平方,要满足自身没有重复的数字,并且跟前面没有重复的数字。
因此问题就差不多解决了。
我这里写的是dfs(i,j,k)
其中k,表示的含义是枚举到第几列,用于输出。
*/

代码


import java.util.Scanner;
public class Main{
    static int[] vis = new int[10];//全程标记数组
    static int[] temVis =new int[10];//用于检测自身是否有重复
    static long[] res = new long[10];//存满足条件的一组组合,用作输出
    static int ant  = 0; //次数
    public static void main(String[] args){
        //i从第一位开始枚举,j从第几个数开始平方枚举,k当前这种情况的第几块数
        dfs(0,0,0);
        System.out.println(ant);
    }

    public static void dfs(int coun,long last, int resindex){
        if(coun == 10){
        //试探到第十个数,自然完成一组组合
            for(int i=0; i<resindex; ++i)
                System.out.print(res[i]+" ");
            System.out.println("-->"+(ant++));
            return;
        }
        for(long i=last; i<=100000; ++i){
            if(isNorepeat((long)i*i)){//如果自身没有重复的数字
            //并且与当前组合的前面数没有重复,说明当前的i*i可以成为组合的一部分
                mark(i*i); //更新全局标记数组

                int len = String.valueOf((long)i*i).length();//i*i长度
                coun += len; //coun表示当前组合的第几个数 
                res[resindex] = i*i; //用于输出,存满足条件的组合数据

                dfs(coun, i+1, resindex+1);

                remark((long)i*i);//返回上一层
                //这里说一下,为什么要返回上一层,
                //首先代码能执行到这里,有俩种情况
                //其一,递归结束条件有return
                //其二,循环终止
                //显然应该是递归终止,所以说明找到了一种情况,所以需要将当前标记消 
                //去,即返回上一层 
                coun -= len; //长度自然要减下去
            }
        }
    }
    //若此j的平方满足条件,则可以加入待组合的后面
    public static void mark(long num){
        if(num ==0){
            vis[0] = 1;
            return;
        }
        while(num != 0){
            vis[(int) (num%10)] = 1;
            num /= 10;
        }
    }
    //判断当前的数自身是否有重复的数字
    public static boolean isNorepeat(long num){
        for(int i=0; i<10; ++i)
            temVis[i] = 0;
        if(num == 0){
            if(vis[0] == 0){
              vis[0] = 1;
             return true;
            }else
                return false;
        }
        while(num != 0){
            if(temVis[(int) (num%10)]==1 || vis[(int) (num%10)]==1 ){
                return false;
            }
            temVis[(int) (num%10)] = 1;
            num /= 10;
        }
        return true;

    }
    //dfs后,返回上一层
    public static void remark(long num){
        if(num == 0){
            vis[0] = 0;
            return;
        }
        while(num != 0){
            vis[(int) (num%10)] = 0;
            num /= 10;
        }
    }
}

全部评论

相关推荐

想干测开的tomca...:让我来压力你!!!: 这份简历看着“技术词堆得满”,实则是“虚胖没干货”,槽点一抓一大把: 1. **项目描述是“技术名词报菜名”,没半分自己的实际价值** 不管是IntelliDoc还是人人探店,全是堆Redis、Elasticsearch、RAG这些时髦词,但你到底干了啥?“基于Redis Bitmap管理分片”是你写了核心逻辑还是只调用了API?“QPS提升至1500”是你独立压测优化的,还是团队成果你蹭着写?全程没“我负责XX模块”“解决了XX具体问题”,纯把技术文档里的术语扒下来凑字数,看着像“知道名词但没实际动手”的实习生抄的。 2. **短项目塞满超纲技术点,可信度直接***** IntelliDoc就干了5个月,又是RAG又是大模型流式响应又是RBAC权限,这堆活儿正经团队分工干都得小半年,你一个后端开发5个月能吃透这么多?明显是把能想到的技术全往里面塞,生怕别人知道你实际只做了个文件上传——这种“技术堆砌式造假”,面试官一眼就能看出水分。 3. **技能栏是“模糊词混子集合”,没半点硬核度** “熟悉HashMap底层”“了解JVM内存模型”——“熟悉”是能手写扩容逻辑?“了解”是能排查GC问题?全是模棱两可的词,既没对应项目里的实践,也没体现深度,等于白写;项目里用了Elasticsearch的KNN检索,技能栏里提都没提具体掌握程度,明显是“用过但不懂”的硬凑。 4. **教育背景和自我评价全是“无效信息垃圾”** GPA前10%这么好的牌,只列“Java程序设计”这种基础课,分布式、微服务这些后端核心课提都不提,白瞎了专业优势;自我评价那堆“积极认真、细心负责”,是从招聘网站抄的模板吧?没有任何和项目挂钩的具体事例,比如“解决过XX bug”“优化过XX性能”,纯废话,看完等于没看。 总结:这简历是“技术名词缝合怪+自我感动式凑数”,看着像“背了后端技术栈名词的应届生”,实则没干货、没重点、没可信度——面试官扫30秒就会丢一边,因为连“你能干嘛”都没说清楚。
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务