蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题

目录

第十一届

约数个数

题目

题解

 代码

代码

寻找 2020

题目

题解 

代码

代码

跑步锻炼

题目

题解

 代码

代码

 代码

灵活使用Excel

平面分割

题目

题解

代码

代码

七段码

题目

题解

代码

成绩统计

题目

题解

代码

代码

代码

单词分析

题目

题解

代码

代码

总结

系列


第十一届

约数个数

题目

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第1张图片

题解

这道题只要for循环暴力破解即可得到正确答案96

 代码

public class Main {
    public static void main(String[] args) {
        int n = 78120;
        int num = 0;
        for (int i = 1; i <= n; i++) {
            if (n % i == 0) {
                num++;
            }
        }
        System.out.println(num);
    }
}

还有一种更高级的解法——约数个数定理

代码

public class Main {
    public static void main(String[] args) {
        // 唯一分解定理
        // 约数个数定理
        //存储每个数分解完后,出现的次数(幂数)
        int[] arr = new int[78120 + 1];
        //记录结果
        long sum = 1;
        //将每个数分解质因数,即将这个数分为质数乘积组成的形式,记录分解的数出现次数。
        int j = 2, n = 78120;
        while (n != j) {
            if (n % j == 0) {
                arr[j]++;
                n = n / j;
            } else {
                j++;
            }
        }
        //最后n==j就是分解到最后一个质数,将这个质数记录
        arr[j]++;
        //根据公式,约数个数=(a1+1)*(a2+1)*(an+1)...a就是质因数出现次数(幂数)
        for (int i = 2; i <= n; i++) {
            if (arr[i] != 0) {
                sum *= (arr[i] + 1);
            }
        }
        //输出结果
        System.out.println(sum);
    }
}

寻找 2020

题目

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第2张图片

题解 

 本题模拟寻找2020的方法即可得到答案16520

双重for循环找同一行、同一列、左上到右下的斜线上的2020

代码

import java.util.Scanner;

public class Main {
    public static final String STRING = "2020";
    static int count = 0;

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

        int n = 300;
        char[][] map = new char[n][n];
        for (int i = 0; i < map.length; i++) {
            map[i] = sc.next().toCharArray();
        }

        sc.close();

        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                judge(i, j, map);
            }
        }

        System.out.println(count);
    }

    public static void judge(int i, int j, char[][] map) {
        //同一行判断
        if (j + 3 < map[0].length) {
            StringBuilder s = new StringBuilder();
            s.append(map[i][j]);
            s.append(map[i][j + 1]);
            s.append(map[i][j + 2]);
            s.append(map[i][j + 3]);
            if (STRING.equals(s.toString())) {
                count++;
            }
        }

        //同一列判断
        if (i + 3 < map.length) {
            StringBuilder s = new StringBuilder();
            s.append(map[i][j]);
            s.append(map[i + 1][j]);
            s.append(map[i + 2][j]);
            s.append(map[i + 3][j]);
            if (STRING.equals(s.toString())) {
                count++;
            }
        }

        //左上到右下的斜线
        if (i + 3 < map.length && j + 3 < map[0].length) {
            StringBuilder s = new StringBuilder();
            s.append(map[i][j]);
            s.append(map[i + 1][j + 1]);
            s.append(map[i + 2][j + 2]);
            s.append(map[i + 3][j + 3]);
            if (STRING.equals(s.toString())) {
                count++;
            }
        }
    }
}

参考:寻找 2020-测试代码007的代码 - 蓝桥云课

代码

import java.util.Scanner;

public class Main {
    static int count = 0;
    static char[][] str = new char[300][300];

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        for (int i = 0; i < str.length; i++) {
            str[i] = input.nextLine().toCharArray();
        }
        f();
        System.out.println(count);
        input.close();
    }

    private static void f() {
        for (int i = 0; i < str.length; i++) {  //遍历行
            for (int j = 0; j < str[i].length; j++) { //遍历列
                if (str[i][j] == '2') {
                    //检查行,第一个2至少为行的倒数第四个,防止数组下行越界
                    if (j <= str[i].length - 4 && str[i][j + 1] == '0' && str[i][j + 2] == '2' && str[i][j + 3] == '0') {
                        count++;
                    }
                    //检查列,第一个2至少为列的倒数第四个
                    if (i <= str.length - 4 && str[i + 1][j] == '0' && str[i + 2][j] == '2' && str[i + 3][j] == '0') {
                        count++;
                    }
                    //检查斜线
                    if (i <= str.length - 4 && j <= str[i].length - 4 && str[i + 1][j + 1] == '0' && str[i + 2][j + 2] == '2' && str[i + 3][j + 3] == '0') {
                        count++;
                    }
                }
            }
        }
    }
}

参考:寻找 2020-糯米丸子的代码 - 蓝桥云课

跑步锻炼

题目

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第3张图片​​​​​​​

题解

这道题直接从2000年1月1日周六一天一天加到2020年10月1日周四即可,再根据题目的条件选择加 1 还是加 2 注意不要忘记判断闰年。答案8879。

 代码

public class Main {
    public static void main(String[] args) {
        //年
        int year = 2000;
        //月
        int month = 1;
        //日
        int day = 1;
        //周
        int week = 6;
        //记录跑步路程
        int sum = 0;

        while (year != 2020 || month != 10 || day != 2) {
            // 周一或者月初(1日)跑 2 千米
            // 同时是周一和月初,小蓝也是跑 2 千米
            if (week == 1 || day == 1) {
                sum += 2;
            } else {
                // 其他时间跑 1 千米
                sum += 1;
            }

            // 4、6、9、11 月有 30 天
            if (month == 4 || month == 6 || month == 9 || month == 11) {
                // 第30天月份加1
                if (day != day % 30) {
                    month += 1;
                }
                //天数 30一循环
                day = day % 30 + 1;
                //特殊 2 月份
            } else if (month == 2) {
                // 判断是否为闰年
                if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                    // 闰年 2 月有 29 天
                    if (day != day % 29) {
                        month += 1;
                    }
                    day = day % 29 + 1;
                    // 平年 2 月有 28 天
                } else {
                    if (day != day % 28) {
                        month += 1;
                    }
                    day = day % 28 + 1;
                }
                // 1、3、5、7、8、10、12 月份 有 31 天
            } else {
                if (month == 12) {
                    // 新的一年
                    if (day != day % 31) {
                        month = 1;
                        year += 1;
                    }
                } else {
                    if (day != day % 31) {
                        month += 1;
                    }
                }
                day = day % 31 + 1;
            }
            // 星期 7 天一循环
            week = week % 7 + 1;
        }
        System.out.println(sum);
    }
}

代码

public class Main {
    public static void main(String[] args) {
        // 周
        int week = 5;
        // 天
        int[] date = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // 记录跑步路程
        int sum = 0;
        for (int year = 2000; year <= 2020; year++) {
            // 判断是否为闰年
            if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
                // 闰年 2 月有 29 天
                date[2] = 29;
            } else {
                // 平年 2 月有 28 天
                date[2] = 28;
            }
            for (int month = 1; month <= 12; month++) {
                for (int day = 1; day <= date[month]; day++) {
                    // 星期 7 天一循环
                    if (week == 7) {
                        week = 1;
                    } else {
                        week++;
                    }
                    // 周一或者月初(1日)跑 2 千米
                    // 同时是周一和月初,小蓝也是跑 2 千米
                    if (day == 1 || week == 1) {
                        sum += 2;
                    } else {
                        // 其他时间跑 1 千米
                        sum++;
                    }
                    if (year == 2020 && month == 10 && day == 1) {
                        System.out.println(sum);
                    }
                }
            }
        }
    }
}

 这道题推荐使用JDK自带的时间类,就不用进行一些复杂的判断。

 代码

import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        // 使用默认时区和区域设置获取日历
        Calendar calendar = Calendar.getInstance();
        // 设置日历字段中的值YEAR , MONTH和DAY_OF_MONTH 。
        // 注意月值为0。 例如,1月份为0,以此类推。
        calendar.set(2000, 0, 1);
        // 记录结果
        int count = 0;
        while (calendar.get(Calendar.YEAR) != 2020 || calendar.get(Calendar.MONTH) != 9 || calendar.get(Calendar.DAY_OF_MONTH) != 2) {
            // 外国人一个星期从星期天开始,所以 星期一是 2
            if (calendar.get(Calendar.DAY_OF_WEEK) == 2 || calendar.get(Calendar.DAY_OF_MONTH) == 1) {
                count += 2;
            } else {
                count++;
            }
            // 天数加 1
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        System.out.print(count);
    }
}

参考: 跑步锻炼-lanqiao0206973762的代码 - 蓝桥云课

灵活使用Excel

这道题没想到还能使用Excel表格解这道题

本人不会操作,放这里给大家看看:跑步锻炼-plutoo的代码 - 蓝桥云课

有会得希望能教教我(。・ω・。)

平面分割

题目

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第4张图片

题解

这是一道找规律的题目,只要找到规律写对应的公式就可以得到答案1391

蓝桥杯给这题的标签是简单(人和人不能一概而论

首先只看直线分割平面的情况:

规律:对于第n条新加入的直线,我们最多能让他与之前的n-1条直线n-1个新的交点
新产生的平面数就是新产生的交点个数(n-1)加上新的直线个数(每次多加一条直线)——>n-1+1=n。

 画图可得表格,由表格可以看出n条直线可以得到1+1+2+3+4+......+n个平面——>用等差数列求和公式化简可得公式:1+n(1+n)/2

只看圆形分割平面的情况:

规律:对于第m个新加入的圆,我们最多能让他与之前的m-1个圆有2(m-1)个新的交点,而新产生的平面数就是2(m-1)个

 画图可得表格,由表格可以看出m个圆可以得到2+2+4+6+8+……+2(m-1)个平面——> 用等差数列求和公式化简可得公式:2+m(m-1)

再来看圆形和直线一起的情况:

1. 如果有m个圆形0条直线,那么由之前的推导可知平面一共有2 + m(m-1)个部分

这时候我们往其中依次加入直线:

加入第一条直线:

每次加入一条直线,我们让直线和每一个圆都相交,那么会产生2m个交点,平面将会新增加2m个,也就是说每加入一条直线只考虑有圆形的话,平面都会新增加2m个,即:

2. 如果有m个圆形1条直线,那么由之前的推导可知平面一共有2 + m(m-1)+2m个

加入第二条直线:

第二条直线会和所有的圆相交则平面将会增加2m个,和原有的直线相交平面会增加2个:

3. 如果有m个圆形2条直线,那么由之前的推导可知平面一共有(2 + m(m-1)+2m)+(2m+2)个

。。。。。。

由以上推理可得 m 个圆和 n 条直线最多能把平面分成多少个部分的公式为:

f(m,n) = (2 + m(m-1)+2m)+(2m+2)+(2m+3)+(2m+4)+......+(2m+n)

           = 2+m^2-m+2mn+(2+3+4+......+n)

           = m^2-m+2mn+1+1+n(1+n)/2

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第5张图片

我写了一个关于平面分割公式的总结感兴趣可以看看:关于平面分割的公式 Java版_疯狂的格式化的博客-CSDN博客

代码

public class Main {
    public static void main(String[] args) {
        // 直接将m=20,n=20代入公式
        System.out.println(20 * 20 + 20 * 20 / 2 + 2 * 20 * 20 - 20 + 20 / 2 + 1);
    }
}

本题反过来思考也是同样的道理:

先确定直线相交的得到的平面数,再依次添加圆

代码

public class Main {
    public static void main(String[] args) {
        // 这里是反过来思考 先确定直线相交的得到的平面数,再依次添加圆
        // 直线
        int n = 20, m = 20, ans = 1;
        for (int i = 1; i <= n; i++) {
            ans += i;
        }

        // 圆
        // 每个圆与直线相交得到 n*2个平面
        // 从第二个圆开始,每个圆与之前的所有的圆都有两个交点,则又会产生 2(m-1) 个平面
        for (int i = 1; i <= m; i++) {
            ans += n * 2 + 2 * (i - 1);
        }
        System.out.println(ans);
    }
}

参考:

​​​​​​https://copyfuture.com/blogs-details/202202271722109084

第十一届蓝桥杯A组省赛平面分割_Alan_Lowe的博客-CSDN博客_蓝桥杯平面分割

2020年蓝桥杯---A组省赛E题---平面分割(数学)_雪岩ding的博客-CSDN博客_蓝桥杯平面切分 

这道题还有动规解法这我是真没想到只能说大佬就是不一样,我只能膜拜!!!

java版动规解法感兴趣的可以看看

七段码

题目

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第6张图片

题解

碰到这道题:

我:???这是我能写的题吗?可以一个个写下来数吗???

大佬:简单题啊!!!dfs+并查集二进制应该也可以做。

人与人之间的差距就像马里亚纳海沟一样深

作为普通人的我们还是安安心心一个个写下来数吧

建议画图来数,这样更直观、方便去重!

一条二极管发光:a、b、c、d、e、f、g 共 7 种

两条二极管发光:ab、af、bg、bc、cg、cd、de、eg、ef、fg 共 10 种

​​​​​​​三条二极管发光:abg、abc、abf、afg、afe、bgf、bge、bgc、bcd、cde、cgf、cge、cgd、def、deg、egf 共 16 种

​​​​​​​​​​​​​​四条二极管发光:

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第7张图片

条二极管发光:

蓝桥杯Java大学C组近三年真题解析(二)——暴力、模拟题_第8张图片

六条二极管发光:可以发现六条二极管发光的情况与一条二极管发光的情况一一对应所以可以认为六条二极管发光 共 7 种

七条二极管发光: 共 1 种

答案:80

关于本题的其他题解之后会更新,敬请期待!!!

代码

public class Main {
    public static void main(String[] args) {
        System.out.println(7 + 10 + 16 + 20 + 19 + 7 + 1);
    }
}

成绩统计

题目

题目描述

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。

输入描述

输入的第一行包含一个整数 n\ (1 \leq n \leq 10^4)n (1≤n≤104),表示考试人数。

接下来 nn 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。

输出描述

输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分 四舍五入保留整数。

输入输出样例

示例

输入

7
80
92
56
74
88
100
0

输出

71%
43%

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

题解

这道题个人认为是考输出格式

java中可以使用C中的printf()格式化输出(自动四舍五​​​​​​​入

也可使用java中Math.round()进行四舍五入

注意:不要使用(int)强制转换,因为它不会四舍五入是直接截断!!!

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //考试人数
        int n = sc.nextInt();
        //及格人数
        int jige = 0;
        //优秀人数
        int youxiue = 0;
        //分数
        int m, i;
        for (i = 0; i < n; i++) {
            m = sc.nextInt();
            //及格
            if (m >= 60) {
                jige++;
            }
            //优秀
            if (m >= 85) {
                youxiue++;
            }
        }
        // 使用C中的printf()格式化输出自动四舍五入 注意输出%要加转义符%(%的转义符就是它本身)
        System.out.printf("%.0f%%\n", jige * 100.0 / n);
        System.out.printf("%.0f%%\n", youxiue * 100.0 / n);
        // double num = jige * 100.0 / n;
        // double num1 = youxiue * 100.0 / n;
        // Math.round() 四舍五入
        // 扩展:Math.ceil() 向上取整 Math.floor() 向下取整
        // System.out.println(Math.round(num) + "%");
        // System.out.println(Math.round(num1) + "%");
        sc.close();
    }
}

这道题还可以使用BigDecimal的一些方法

​​​​​​​【java】BigDecimal.setScale用法总结

代码参考自:https://www.lanqiao.cn/questions/191736/

不出意外代码提交后无法通过大家可以试试下面的测试用例看看是什么问题

输入

99 100 64 68 67 69 39 28 96 71 77 34 77 54 81 37 42 51 58 76 70 87 61 60 30 82 30 66 86 83 75 84 87 93 90 69 85 43 57 82 20 13 39 65 98 36 24 46 77 30 44 12 60 94 37 48 87 62 97 49 34 92 85 43 94 67 29 90 88 85 25 52 43 37 28 96 51 58 87 79 88 21 99 54 41 14 83 30 18 82 89 86 81 52 92 46 61 85 64 86

输出

58%

27%

下面的代码经过我的修改后可以通过

代码

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //考试人数
        int n = sc.nextInt();
        //及格人数
        double pass = 0;
        //优秀人数
        double good = 0;
        // 学生分数
        int m, i;
        for ( i = 0; i < n; i++) {
            m = sc.nextInt();
            //及格
            if (m >= 60) {
                pass++;
                //优秀
                if (m >= 85) {
                    good++;
                }
            }
        }
        BigDecimal bg1 = new BigDecimal(pass / n);
        BigDecimal bg2 = new BigDecimal(good / n);
        // BigDecimal.setScale主要用于对BigDecimal数据小数点后的位数进行 进位、舍位、截断等操作
        pass = bg1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        good = bg2.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        String p = String.valueOf(pass);
        String g = String.valueOf(good);
        if (p.substring(2).length() < 2) {
            System.out.println(p.substring(2) + "0" + "%");
        } else {
            System.out.println(p.substring(2) + "%");
        }
        if (g.substring(2).length() < 2) {
            System.out.println(g.substring(2) + "0" + "%");
        } else {
            System.out.println(g.substring(2) + "%");
        }
    }
}

​​​​​​​当然使用NumberFormat也是不错的方法

代码参考:https://www.lanqiao.cn/questions/213759/

代码

import java.text.NumberFormat;
import java.util.Scanner;

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

        int[] grade = new int[people];
        for (int i = 0; i < people; i++) {
            grade[i] = p.nextInt();
        }
        // 返回百分比格式的NumberFormat实例
        NumberFormat format = NumberFormat.getPercentInstance();
        //设置保留几位小数
        format.setMaximumFractionDigits(0);
        int m = 0,n = 0;
        for (int j : grade) {
            //算及格率
            if (j >= 60) {
                m++;
                //算优秀率
                if (j >= 85) {
                    n++;
                }
            }
        }
        double jige = (double) m / people;
        System.out.println(format.format(jige));
        double youxiu = (double) n / people;
        System.out.println(format.format(youxiu));
    }
}

单词分析

题目

题目描述

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。

现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。

输入描述

输入一行包含一个单词,单词只由小写英文字母组成。

对于所有的评测用例,输入的单词长度不超过 1000。

输出描述

输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。

第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。

输入输出样例

示例 1

输入

lanqiao

输出

a
2

示例 2

输入

longlonglongistoolong

输出

o
6

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

题解

这道题非常的简单直接for循环暴搜,也不会超时,毕竟输入的单词长度不超过 1000

只需要注意有多个字母出现的次数相等,输出字典序最小的那个

代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int[] count = new int[26];
        for (int i = 0; i < s.length(); i++) {
            count[s.charAt(i)-'a']++;
        }
        int max=0;
        for(int i=1;i<26;i++){
            if(count[i]>count[max]){
                max=i;
            }
        }
        System.out.printf("%c\n%d",max+'a',count[max]);
    }
}

​​​​​​​这题使用HashMap也是一个不错的选择,但有一个问题那就是HashMap的键不是有序的,所以在程序中要特殊判断一下,不过在蓝桥官网你不特殊判断也可以通过,只能说测试数据太水。比如你注释掉下面程序的第20--23行代码然后运行程序输入gggggbbbassssbs你会发现输出的是错误答案 s 5,然而正确答案肉眼可见是 g 5(通过的人只能说是运气好,祝大家考试时都有这样的好运)

参考:https://www.lanqiao.cn/questions/190455/

代码

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        Map map = new HashMap<>();
        for (char a : str.toCharArray()) {
            if (map.containsKey(a)) {
                map.put(a, map.get(a) + 1);
            } else {
                map.put(a, 1);
            }
        }
        int max = 0;
        char c = 0;
        for (Map.Entry m : map.entrySet()) {
            if (m.getValue() == max && m.getKey() < c) {
                c = m.getKey();
                continue;
            }
            if (m.getValue() > max) {
                max = m.getValue();
                c = m.getKey();
            }
        }
        System.out.println(c + "\n" + max);
    }
}

总结

这些题在第十一届中属于简单题(我认为不是),在考试中应该是必拿的分考的是我们模拟某种事件将其转换为程序的能力和发现规律的能力,此类题型一般是填空题或数据范围较小的编程题,因为暴力模拟一般会超时

其他题目持续更新中。。。。。。

系列

蓝桥杯Java大学C组近三年真题解析(一)——暴力、模拟题_疯狂的格式化的博客-CSDN博客

蓝桥杯Java大学C组近三年真题解析(三)——暴力、模拟题_疯狂的格式化的博客-CSDN博客

你可能感兴趣的:(蓝桥杯,蓝桥杯,java,算法)