ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

第七届蓝桥杯Java B组题解

2022-02-06 15:35:09  阅读:196  来源: 互联网

标签:Java int 题解 蓝桥 abs static && public Math


A.煤球数目

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

有一堆煤球,堆成三角棱锥形。具体: 第一层放 1个, 第二层 3个(排列成三角形), 第三层 6个(排列成三角形), 第四层 10个(排列成三角形), … 如果一共有 100层,共有多少个煤球?

题目分析

找规律,观察到第i层煤球数目为i*(i+1)/2

题解

171700
/**
 * @Description
 * @Author:PrinceHan
 * @CreateTime:2022/2/5 08:33
 */
public class Main {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum += i * (i + 1) / 2;
        }
        System.out.println(sum);
    }
}

B.生日蜡烛

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

某君从某年开始每年都举办一次生日 party,并且每次都要吹熄与年龄相同根数的蜡烛。

现在算起来,他一共吹熄了 236 根蜡烛。

请问,他从多少岁开始过生日 party 的?

请输出他开始过生日 party 的年龄数。

题目分析

可以先初始化蜡烛数组,在数组中找一段连续的区间和使和等于236。可以维护一个窗口,当和小于236时,滑动右窗口,当和大于236时,滑动左侧窗口,等于236时,输出左窗口的值,即为所求。

题解

26
/**
 * @Description
 * @Author:PrinceHan
 * @CreateTime:2022/2/5 08:39
 */
public class B {
    public static void main(String[] args) {
        int sum = 0;
        int[] arr = new int[101];
        for (int i = 1; i <= 100; i++) {
            arr[i] = i;
        }
        for (int i = 1, j = 1; i <= 100 && j <= 100; ) {
            if (sum < 236) sum += arr[j++];
            if (sum == 236) {
                System.out.println(i);
                System.exit(0);
            }
            if (sum > 236) {
                sum -= arr[i];
                i++;
            }
        }
    }
}

C.凑算式

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

     B      DEF
A + --- + ------- = 10
     C      GHI

这个算式中 A ~ I 代表 0 ~ 9 的数字,不同的字母代表不同的数字。

比如: 6+8/3+952/7146+8/3+952/714 就是一种解法, 5+3/1+972/4865+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

题目分析

本质上是一道求全排列的问题,用到了深搜,只是对数组的元素进行了一个处理。

题解

29
/**
 * @Description
 * @Author:PrinceHan
 * @CreateTime:2022/2/5 08:48
 */
public class C {
    static int[] nums = new int[10];
    static boolean[] vis = new boolean[10];
    static int ans;

    public static void main(String[] args) {
        dfs(1);
        System.out.println(ans);
    }

    public static void dfs(int step) {
        if (step == 10 && check(nums)) {
            ans++;
            return;
        }
        for (int i = 1; i < 10; i++) {
            if (!vis[i]) {
                nums[step] = i;
                vis[i] = true;
                dfs(step + 1);
                vis[i] = false;
            }
        }
    }

    public static boolean check(int[] a) {
        int num1 = a[3];
        int num2 = a[4] * 100 + a[5] * 10 + a[6];
        int num3 = a[7] * 100 + a[8] * 10 + a[9];
        if (a[1] * num1 * num3 + a[2] * num3 + num2 * num1 == 10 * num1 * num3) return true;
        return false;
    }
}

D.分小组

题目描述

本题为代码补全填空题。

9名运动员参加比赛,需要分3组进行预赛。 有哪些分组的方案呢?

我们标记运动员为 A,B,C,… I。

下面的程序列出了所有的分组方法。

源代码

import java.util.*;
public class Main
{
    public static String remain(int[] a)
    {
        String s = "";
        for(int i=0; i<a.length; i++){
            if(a[i] == 0) s += (char)(i+'A');
        }    
        return s;
    }
    
    public static void f(String s, int[] a)
    {
        for(int i=0; i<a.length; i++){
            if(a[i]==1) continue;
            a[i] = 1;
            for(int j=i+1; j<a.length; j++){
                if(a[j]==1) continue;
                a[j]=1;
                for(int k=j+1; k<a.length; k++){
                    if(a[k]==1) continue;
                    a[k]=1;
                    System.out.println(____________________________);
                    a[k]=0;
                }
                a[j]=0;
            }
            a[i] = 0;
        }
    }
    
    public static void main(String[] args)
    {
        int[] a = new int[9];        
        a[0] = 1;
        
        for(int b=1; b<a.length; b++){
            a[b] = 1;
            for(int c=b+1; c<a.length; c++){
                a[c] = 1;
                String s = "A" + (char)(b+'A') + (char)(c+'A');
                f(s,a);
                a[c] = 0;
            }
            a[b] = 0;
        }
    }
}

在这里插入图片描述

题目分析

本题是一道代码填空题,有一定的做题技巧。首先代码中给的函数或者是变量一定会用到,可以通过打断点,调试程序是怎么运行的。在main()方法得到的是前三个字母,并将s通过参数传递给f()方法,这里意识到可能会拼接字符串,f()方法是为了获得中间三位的字符串,通过remain()方法得到包含剩余字母的字符串,将字符串拼接,打印输出即可。

题解

System.out.println(s + " " + (char) (i + 'A') + (char) (j + 'A') + (char) (k + 'A') + " " + remain(a));

E.抽签

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全。

X星球要派出一个 5 人组成的观察团前往 W 星。

其中:

A 国最多可以派出 4 人。

B 国最多可以派出 2 人。

C 国最多可以派出 2 人。

那么最终派往 W 星的观察团会有多少种国别的不同组合呢?

下面的程序解决了这个问题。 数组 a[] 中既是每个国家可以派出的最多的名额。 程序执行结果为:

DEFFF
CEFFF
CDFFF
CDEFF
CCFFF
CCEFF
CCDFF
CCDEF
BEFFF
BDFFF
BDEFF
BCFFF
BCEFF
BCDFF
BCDEF
....
(以下省略,总共101行)

下面的代码就是为了这个目的的,请仔细阅读源码,并填写划线部分缺少的代码。

源代码

import java.util.*;
public class Main
{
    public static void f(int[] a, int k, int n, String s)
    {
        if(k==a.length){ //考虑到了所有的国家
            if(n==0) System.out.println(s);//n==0说明取到了5个人
            return;
        }
        
        String s2 = s;//保存已经选择的组合
        for(int i=0; i<=a[k]; i++){
            ______________________;
            s2 += (char)(k+'A');
        }
    }
    
    public static void main(String[] args)
    {
        int[] a = {4,2,2,1,1,3};
        
        f(a,0,5,"");
    }
}

题目分析

观察f()方法,有出口,意识到可能要用到递归。观察到main()方法中f()方法传参k = 0,n = 5,递归结束条件为ka.length,n0则要让k增大,n减小,在代码填空处要完成这些操作。

for (int i = 0; i <= a[k]; i++) {
    f(a, k+1,n-i,s2);//k+1访问下一个国家,n-i表示从当前国家中减去选择的人数
    s2 += (char) (k + 'A');
}

F.方格填数

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

如下的 10 个格子:

   +--+--+--+
   |  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+

填入 0 ~ 9 的数字。要求:连续的两个数字不能相邻。 (左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

题目分析

本质上是一道全排列,但要求连续的两个数字不相邻,不相邻指的是差的绝对值不等于1,判断一下即可。

题解

1580
/**
 * @Description
 * @Author:PrinceHan
 * @CreateTime:2022/2/6 09:41
 */
public class F {
    static int[] nums = new int[10];
    static boolean[] vis = new boolean[10];
    static int ans;

    public static void main(String[] args) {
        dfs(0);
        System.out.println(ans);
    }

    public static void dfs(int step) {
        if (step == 10 && check(nums)) {
            ans++;
            return;
        }
        for (int i = 0; i < 10; i++) {
            if (!vis[i]) {
                nums[step] = i;
                vis[i] = true;
                dfs(step + 1);
                vis[i] = false;
            }
        }
    }

    public static boolean check(int[] a) {
        return Math.abs(a[0] - a[1]) != 1 && Math.abs(a[1] - a[2]) != 1 && Math.abs(a[3] - a[4]) != 1 && Math.abs(a[4] - a[5]) != 1 && Math.abs(a[5] - a[6]) != 1 && Math.abs(a[7] - a[8]) != 1 && Math.abs(a[8] - a[9]) != 1 && Math.abs(a[0] - a[4]) != 1 && Math.abs(a[1] - a[5]) != 1 && Math.abs(a[2] - a[6]) != 1 && Math.abs(a[3] - a[7]) != 1 && Math.abs(a[4] - a[8]) != 1 && Math.abs(a[5] - a[9]) != 1 && Math.abs(a[0] - a[3]) != 1 && Math.abs(a[1] - a[4]) != 1 && Math.abs(a[2] - a[5]) != 1 && Math.abs(a[0] - a[5]) != 1 && Math.abs(a[1] - a[6]) != 1 && Math.abs(a[3] - a[8]) != 1 && Math.abs(a[4] - a[9]) != 1 && Math.abs(a[4] - a[7]) != 1 && Math.abs(a[5] - a[8]) != 1 && Math.abs(a[6] - a[9]) != 1;
    }
}

G.剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。

在这里插入图片描述

现在你要从中剪下 5张来,要求必须是连着的。

(仅仅连接一个角不算相连) 比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

在这里插入图片描述

在这里插入图片描述

请你计算,一共有多少种不同的剪取方法。

题目分析

一开始做的时候想着用dfs搜一下,但是运行起来方案数量比正确答案少,看了看题解发现用dfs无法解决“T”型方案。借鉴了B站上的题解,剪邮票
从12个里面选择5个,可以初始化一个数组,长度为12,中有5个1,对这个数组进行全排列,再判断选取的是否联通,判断联通问题可以用dfs处理,在进行全排列时,要考虑全排列重复的情况,进行去重,在C++中有现成的全排列函数:

 #include <algorithm>
 bool next_permutation(iterator start,iterator end)

可以得到不重复的全排列,但在Java中没有全排列的方法,一般通过手写dfs来实现。

题解

116
/**
 * @Description
 * @Author:PrinceHan
 * @CreateTime:2022/2/6 10:20
 */
public class G {
    static int[] a = {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1};//邮票数组
    static int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
    static boolean[] vis = new boolean[12];
    static int ans;

    public static void main(String[] args) {
        int[] path = new int[12];
        f(0, path);
        System.out.println(ans);
    }

    static void dfs(int[][] g, int x, int y) {
        g[x][y] = 0;//将1的部分标记为0
        for (int i = 0; i < 4; i++) {
            int xx = x + dx[i];
            int yy = y + dy[i];
            if (in(xx, yy) && g[xx][yy] == 1) {
                dfs(g, xx, yy);
            }
        }
    }

    static boolean check(int[] path) {
    	//path数组可以看作是存放全排列结果的容器,下文中的path数组也是
        int[][] g = new int[3][4];//g即graph,表示选择的哪一块
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                if (path[i * 4 + j] == 1) g[i][j] = 1;//与下标对应上
                else g[i][j] = 0;
            }
        }
        int cnt = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                if (g[i][j] == 1) {
                    dfs(g, i, j);//如果这块是选择的一块,从这一块开始深搜
                    cnt++;
                }
            }
        }
        return cnt == 1;//一次深搜证明联通
    }
    //全排列函数,path数组可以看作是存放全排列结果的容器
    static void f(int k, int path[]) {
        if (k == 12) {
            if (check(path)) ans++;
        }
        for (int i = 0; i < 12; i++) {
        //去重,如果选取了当前的,并且当前的与前一步的结果一样,但是前一步还没有选择,跳过这一步
            if (i > 0 && a[i] == a[i - 1] && !vis[i - 1]) continue;
            if (!vis[i]) {
                vis[i] = true;
                path[k] = a[i];
                f(k + 1, path);
                vis[i] = false;
            }
        }
    }

    static boolean in(int x, int y) {
        return x >= 0 && x < 3 && y >= 0 && y < 4;
    }
}

标签:Java,int,题解,蓝桥,abs,static,&&,public,Math
来源: https://blog.csdn.net/weixin_51624761/article/details/122798142

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有