当前位置: 首页 > news >正文

第十六届蓝桥杯省赛JavaB组题解

A 逃离高塔

第一道填空题很简单,根据题意跑一边循环即可,一共是202个符合条件的数

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int ans=0;
        for(long i=0;i<=2025;i++){
            if((i*i*i)%10==3)
                ans++;

        }
        System.out.println(ans);
    }

需要注意的是循环变量要定义成long型,不然三次方会爆int,只会得到153个数字

B消失的蓝宝

这题想了一会没思路直接跳过了...

C电池分组

要将数组分成两块,并使它们的异或和相同,直接暴力求解是很繁琐的

异或是同一个比特位上两个数相同则为0,不同为1,要找出异或和相同的两组数,假设已经找到这两组数了,这个时候两个异或和是相同的,对他们做异或运算结果是0

也就是说,假设a^b^c 和d^e是我们找到的两组异或和相同的两组数,那么(a^b^c)^(d^e)=0

而且异或运算满足交换律,所以我们直接对输入的所有数字做异或运算,看最后的结果如果为0就代表满足题意

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t=0;
        t=scanner.nextInt();
        int x=0;
        while((t--)>0){
            int n = scanner.nextInt();
            x=0;
            for(int i=0;i<n;i++){
                x^=scanner.nextInt();
            }
            if(x==0){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
        }
    }
}

不过我在考场上第一时间没有想到这个思路,我是后面回过头来在看的这道题目,我观察了一下题目,发现当某个比特位上出现1的个数为偶数时符合题意,为奇数时则不符合题意,所以我就统计所有数每个比特位上1的个数,如果某个比特位上1的个数为奇数则直接输出NO,否则就是符合题意的,考完后仔细想了一下,也算是歪打正着做对了

当某个位上出现1的个数为偶数个时,这些1的异或和是0,和剩下的0在做异或结果也是0

当某个位上出现1的个数为奇数个时,这些1的异或和是1,和剩下的0在做异或结果为1,那么最后所有数的异或和绝不会为0

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t=0;
        t=scanner.nextInt();
        int x=0;
        //存储每个比特位上1的个数
        int[] bit=new int[32];
        int cnt=0;
        boolean istrue=true;
        while((t--)>0){
            int n = scanner.nextInt();
            istrue=true;
            //清空上次结果
            for(int i=0;i<32;i++){
                bit[i]=0;
            }
            for(int i=0;i<n;i++){
                cnt=0;
                x=scanner.nextInt();
                while(x>0){

                    if((x&1)>0){
                        bit[cnt]++;
                    }
                    x>>=1;
                    cnt++;
                }

            }

            for(int i=0;i<32;i++){
                if(bit[i]%2==1){
                    istrue=false;
                }
            }
            
            if(istrue){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
        }
    }

}

D魔法科考试

 这题没想到太好的思路,直接提前做了一个素数筛,然后两层循环暴力求解,只能过60%测试用例

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        //素数筛
        boolean[] isz=new boolean[40010];
        isz[1]=true;
        for(int i=2;i*i<=40001;i++){
            if(!isz[i]){
                for(int j=i+i;j<=40001;j+=i){
                    isz[j]=true;
                }
            }
        }

        int n=scanner.nextInt();
        int m=scanner.nextInt();
        int[] a=new int[n];
        int[] b=new int[m];
        for(int i=0;i<n;i++){
            a[i]=scanner.nextInt();
        }
        for(int i=0;i<m;i++){
            b[i]=scanner.nextInt();
        }
        int s=0,sum=n+m,ans=0;
        boolean[] vis=new boolean[sum+1];
        for(int i=0;i<n;i++){

            for(int j=0;j<m;j++){
                
                s=a[i]+b[j];
                if(s<=sum&&!isz[s]&&!vis[s]){
                    ans++;
                    vis[s]=true;
                }
            }
        }

        System.out.println(ans);
    }
}

E爆破

 刚开始看见又是圆心又是半径的,直接就跳过了,看完后面回过头来发现这就是一个最小生成树

直接暴力选边是不可取的,时间复杂度高不说,无法保证每个圆都连通,题目提到如果两个魔法阵相交,可以一起引爆,可以自己选择连边让孤立的圆与其他圆连接,当时就直接想到了最小生成树

注意,题目中所说两个魔法阵相交的意思是圆心之间的距离小于等于半径之和

解题思路是,将坐标系当作一个图,我们将每个圆当作图中的一个点,以输入的下标当作圆的编号,开始时假设每个圆与其他所有圆都有一个无向边,边长是两圆心之间的距离减去半径之和,也就是想让这两个圆相交的最小代价,假设一共n个圆,那么就有n*(n-1)/2条边,存进数组中根据边长排序,后面利用并查集从小到大选边

相交的两个圆的边长是负数,在处理时不用计入答案,标记后直接跳过就好

import java.util.*;

public class Main {

    public static class edge{
        private int x;
        private int y;
        private double r;
        public edge(int x, int y, double r){
            this.x = x;
            this.y = y;
            this.r = r;
        }
    }

    private static int[] father;
    private static int n,m;
    //初始化
    public static void init(){
        father = new int[n+1];
        for(int i=0;i<father.length;i++){
            father[i] = i;
        }

    }
    //查找父节点,同时更新父节点信息
    public static int find(int x){

        return father[x]==x?x:(father[x]=find(father[x]));
    }

    public static double kruskal(edge[] edges){
        //初始化父亲数组
        init();
        double ans=0;
        int fx=0,fy=0;
        for(edge e:edges){
            fx=find(e.x);
            fy=find(e.y);

            if(fx!=fy){
                father[fx]=fy;
                //大于0时计入答案
                if(e.r>0){
                    ans+=e.r;
                }
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m=n*(n-1)/2;
        int cnt=0;

        int[] x = new int[n];
        int[] y = new int[n];
        int[] r = new int[n];
        edge[] edges = new edge[m];

        for(int i=0;i<n;i++){
            x[i] = scanner.nextInt();
            y[i] = scanner.nextInt();
            r[i] = scanner.nextInt();
        }
        double line=0;
        int lx=0,ly=0;
        for(int i=0;i<n;i++){
            for(int j=i+1;j<n;j++){

                lx=x[i]-x[j];
                ly=y[i]-y[j];
                line=Math.sqrt((lx*lx)+(ly*ly))-r[i]-r[j];
                edges[cnt]=new edge(i,j,line);
                cnt++;
            }
        }
        //按边的长度从小到大排序
        Arrays.sort(edges,new Comparator<edge>(){
            public int compare(edge e1, edge e2) {
                double x=e1.r-e2.r;
                if(x<0) return -1;
                if(x>0) return 1;
                return 0;
            }
        });
        double ans=kruskal(edges);

        System.out.printf("%.2f",ans);
    }
}

剩下的三题不确定思路是否正确,等后面我研究一下再发

相关文章:

  • Ansible-Playbook详解
  • 第十六届蓝桥杯大赛软件赛省赛 C/C++ 大学B组
  • 【图像处理基石】什么是抗锯齿(Anti-Aliasing)?
  • 上海AI实验室开源Intern VL3系列模型:整体文本性能优于 Qwen2.5 系列
  • maven编译jar踩坑[sqlite.db]
  • [福游宝——AI智能旅游信息查询平台]全栈AI项目-阶段一:Vite前端开荒
  • 【模块化拆解与多视角信息1】基础信息:隐藏的筛选规则——那些简历上没说出口的暗号
  • 使用 Visual Studio 2022 (VS2022) 编译 FreeCAD 1.0.0 的详细教程
  • Model Context Protocol (MCP) - 尝试创建和测试一下MCP Server
  • 探秘Transformer系列之(26)--- KV Cache优化 之 PD分离or合并
  • swift菜鸟教程29-30(泛型,访问控制)
  • 文件上传基本原理靶场实现
  • SpringBoot(一)
  • 融合动态权重与抗刷机制的网文评分系统——基于优书网、IMDB与Reddit的混合算法实践
  • 【源码】SpringBoot源码分析
  • 301.找出3位偶数
  • [ctfshow web入门] web37
  • 【软考系统架构设计师】系统配置与性能评价
  • 使用Python建模量子隧穿
  • String类基本使用
  • 钓鱼网站服务器放香港危险吗/网店代运营
  • 做网站大概要多久/站长工具怎么关掉
  • 上海网站建设代码/百度推广注册
  • 做调查问卷哪个网站好/网站关键词怎么写
  • 沙河做网站/线上推广渠道主要有哪些
  • 专做定制型网站/怎样建立自己的网站平台