历届蓝桥杯省赛Java B组真题思路总结

历届蓝桥杯Java B组思路总结

写在前面

蒟蒻一枚,写此篇博客作为我的赛前突击,基本每年后面的两个大题或者是很难的题我都没有做,我的目标是能混省二我就谢天谢地了~~

13年省赛

世纪末的星期

此类题目主要是考察对时间的操作,主要用到的API是LocalDate,LocalTime,Calendar,关于对时间的操作很容易考,所以一定掌握这几个类。

马虎的算式

此题就是暴力破,五重for循环,注意一下限制条件就可以了

振兴中华

一看题目就可以知道这是一道搜索的题目,所以我们首先考虑深搜和广搜

public class Main {

    public static void main(String[] args) {
        int m = dfs(0, 0);
        System.out.println(m);
    }

    // dfs
    public static int dfs(int i, int j) {
        if (i == 3 || j == 4) {
            return 1;
        }
        return dfs(i + 1, j) + dfs(i, j + 1);
    }
}

黄金连分数

根据找规律我们可以发现这是考察斐波那契数列,某个相邻两项的比值。

关于求解斐波那契数列的问题由于它的后期数很大,所以我们用API进行大数操作,我们就知道要用BigIntegerBigDecimal来做。

public class Main {
    public static void main(String[] args) {
        BigInteger a = BigInteger.ONE;
        BigInteger b = BigInteger.ONE;
        for (int i = 3; i < 500; i++) {
            BigInteger t = b;
            b = a.add(b);
            a = t;
        }
        BigDecimal div = new BigDecimal(a, 110).divide(new BigDecimal(b, 110), BigDecimal.ROUND_HALF_DOWN);
        System.out.println(div.toPlainString().substring(0, 103));
    }
}

有理数类

填空题,考察面向对象,暴力试皆可

三部排序

填空题,快排的变种,暴力试即可

错误票据

枚举,注意输入的时候需要吃掉一个换行符input.nextline()

幸运数

日后有缘再续

带分数

日后有缘再续

连号区间数

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = sc.nextInt();
        }
        sc.close();
        int ans = 0;
        for (int i = 0; i < arr.length; i++) {
            int max = Integer.MIN_VALUE;
            int min = Integer.MAX_VALUE;
            for (int j = i; j < arr.length; j++) {
                max = Math.max(max, arr[j]);
                min = Math.min(min, arr[j]);
                if ((max - min + 1) == j - i + 1) {
                    ans++;
                }
            }
        }
        System.out.println(ans);
    }
}

14年省赛

武功秘籍

思维题,不需要编程,读懂题意,直接动手画就可以了

切面条

规律思维题,找规律,1+2的n次方

猜字母

在这里插入图片描述

public class Main {

    public static void main(String[] args) {
        char[] arr = new char[2014];
        int index = 0;
        for (int i = 0; i < 106; i++) {
            for (int j = 0; j < 19; j++) {
                arr[index++] = (char) ('a' + j);
            }
        }
        // System.out.println(Arrays.toString(arr));
        int len = 2014;
        while (len != 1) {
            int mm = 0;
            for (int i = 1; i < len; i += 2) {
                arr[mm++] = arr[i];
            }
            len = mm;
        }
        System.out.println(arr[0]);
    }
}

大衍数列

老师异常激动的说这简直就是水题,太简单了,求偶数项,so,确实水,我都会,hhh

圆周率

填空题,答案:4/(n-1),过~

奇怪的分式

关键思路在于枚举四个数并且求两个数的最大公约数,求公约数是关键

//递归求解最大公约数
public static int gcd(int a, int b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
}

扑克排序

全排列,递归框架,然后check求解,求解全排列用递归

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {
        char[] a = { 'A', 'A', '2', '2', '3', '3', '4', '4' };
        fun(a, 0);
        for (String c : set) {
            System.out.println(c);
        }
    }

    // 去重
    static Set<String> set = new HashSet<>();

    // 递归框架求解全排列
    public static void fun(char[] a, int k) {
        // 判断
        if (k == a.length) {
            String s = new String(a);
            if (check(s)) {
                set.add(s);
            }
        }
        // 全排列
        for (int i = k; i < a.length; i++) {
            char t = a[k];
            a[k] = a[i];
            a[i] = t;

            fun(a, k + 1);

            // 回溯
            t = a[k];
            a[k] = a[i];
            a[i] = t;
        }
    }

    // 检查
    public static boolean check(String s) {
        if (s.lastIndexOf('A') - s.indexOf('A') == 2 && s.lastIndexOf('2') - s.indexOf('2') == 3
                && s.lastIndexOf('3') - s.indexOf('3') == 4 && s.lastIndexOf('4') - s.indexOf('4') == 5) {
            return true;
        } else {
            return false;
        }
    }
}

分糖果

模拟题,根据情况仔细模拟就可以了,核心思路就是一个圈,用数组表示,先减去一半,然后再把后面的一半加到前面的数上面,最后一个数是将首尾的一半加上。

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();// 输入几个孩子
        // 用数组表示一个圈
        int[] a = new int[n];
        for (int i = 0; i < a.length; i++) {
            a[i] = input.nextInt();
        }
        int ans = 0;

        while (true) {
            int t = a[0];
            for (int i = 0; i <= n - 2; i++) {
                a[i] -= a[i] / 2;// 先减去一半 再加上下一项的一半
                a[i] += a[i + 1] / 2;
                if ((a[i] & 1) == 1) {
                    ans++;
                    a[i]++;
                }
            }
            // 最后一项也要进行一样的操作
            a[n - 1] -= a[n - 1] / 2;
            a[n - 1] += t / 2;
            if ((a[n - 1] & 1) == 1) {
                ans++;
                a[n - 1]++;
            }

            // 检验
            if (check(a, n)) {
                System.out.println(ans);
                break;
            }
        }

    }

    // 检验
    public static boolean check(int[] a, int n) {
        int t = a[0];
        for (int i = 1; i < n; i++) {
            if (a[i] != t) {
                return false;
            }
        }
        return true;
    }
}

地宫取宝

记忆型递归

矩阵翻硬币(有点难,弃了~~)

emmmm。。。。。。

15年省赛

三角形面积

这。。。小学就学过的题目,水题。。。过了过了

立方变自身

暴力破,只需要知道范围就可以了,我们可以用计算机求得左区间肯定是小于99,因为当99的立方是个很大的数,不可能相加等于99

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        int count = 0;
        for (int i = 1; i < 99; i++) {
            int m = i * i * i;
            String s = String.valueOf(m);
            int sum = 0;
            for (int j = 0; j < s.length(); j++) {
                int a = Integer.parseInt(String.valueOf(s.charAt(j)));
                sum += a;
            }
            if (sum == i) {
                count++;
            }
        }
        System.out.println(count);
    }
}

三羊献瑞

解法一:暴力破,超级多重for循环,但是很容易晕。。。

第二种解法是用数学思维,根据进位的变化来推出某些数,然后再用循环来求解这样的循环就会简便的多

循环节长度

老师说这题很难,当时难倒过众好汉,难在特例很难给出,v.size()-v.indexOf(n)

九数组分数

九个数组组成一个分数,此题考查全排列递归框架,然后递归多分支探索,之后我们需要回溯,所以我们只需要填写回溯部分就可以了,回溯部分就是我们递归之前的语句。

//全排列的实现算法 递归+交换
package Test.Arithmetic;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        perm(new int[] { 1, 2, 3, 4 }, 0, 3);
    }

    // 递归输出全排列
    public static void perm(int[] array, int start, int end) {
        if (start == end) {
            System.out.println(Arrays.toString(array));
        } else {
            for (int i = start; i <= end; i++) {
                swap(array, start, i);
                perm(array, start + 1, end);
                swap(array, start, i);
            }
        }
    }

    // 交换数字
    public static void swap(int[] array, int i, int j) {
        int t = array[i];
        array[i] = array[j];
        array[j] = t;
    }
}

在这里插入图片描述

加法变乘法

此题很有意思,此年的一些题目都是一些很新奇的解决方案,比如这道题目,解题思路就很新颖,一开始我看了一会没有思路,听老师一讲,醍醐灌顶,老师说有两个方法,方法一就是比较普通的办法,等差数列,比较麻烦。ps:我连这个都没想到。然后第二个方法比较新奇,就是因为是只改变了两个部分,所以我们用新的减去旧的再把这两个加起来,肯定等于最后的结果相减。

public class Main {

    public static void main(String[] args) {
        for (int i = 1; i <= 46; i++) {
            for (int j = i + 2; j <= 48; j++) {
                if (i * (i + 1) - (i + i + 1) + j * (j + 1) - (j + j + 1) == 2015 - 1225) {
                    System.out.println(i + " " + j);
                }
            }
        }
    }
}

牌型种树(重看)

思维题,思维上有点难,,emmm,先过,日后有缘再续

饮料换购

老师说是水题,但我却没想到,,ctml。。。我真愚蠢,我真笨,我真是蒟蒻!!!

思维题,这道题目老师说很简单,但是我却想麻烦了,我居然还蠢到去用递归来解决,结果溢出找错找了半天,最后无果而终,nnp,其实这道题目的思维很简单,用迭代就可以实现,就那几个点拿捏好了就可以了,第一个是你每消耗三瓶就会产生一瓶,所以你其实是从总的瓶数里面减去了两瓶,然后我们拿一个ans来计数,初始值为零,每次都加上三个瓶数,因为每次都是消耗三个,并且前面消耗了三个产生了一个新的,所以每次并不会多加,循环的条件就是瓶数大于等于三,最后将不到三瓶的数目加给ans。

代码实现

public class Main {

	public static void main(String[] args) {
		int ans = 0;
		int n=100;
		while(n >= 3) {
			n -= 2;
			ans += 3;
		}
		ans += n;
		System.out.println(ans);
	}
}

垒骰子(太难了,弃了)

dp,矩阵,,,太难了。。。。

生命之树(太难了,弃了)

。。。。。

16年省赛

煤球数目

规律题,静下心来找规律就可以了,千万不要想的太难

生日蜡烛

数学问题,等差数列前n项和公式,在这里插入图片描述

public class Main {
    public static void main(String[] args) {
        for (int i = 1; i < 100; i++) {
            int t = i * (i - 1) / 2;
            if ((236 - t) % i == 0) {
                System.out.println((236 - t) / i);
            }
        }
    }
}//总感觉是似曾相识啊!!!

凑算式

又是全排列,固定套路,递归,回溯即可

分小组

填空题,过了,

抽签

填空题。。。递归

方格填数

提交结果题,全排列

剪邮票

难题开始,

四平方和

枚举优化(hash缓存)

取球博弈

日后有缘再续

压缩变换

hash查找+标注+区间树

ps:这一年的题居然考了三道全排列,但感觉16年的题目普遍偏难,当年要是我考的话可能连省三都没有。。。

17年省赛

购物单

不用编程,思维题,用Excel表格做,水题

纸牌三角形

全排列问题,

import static java.lang.Math.*;

/**
 * 全排列模板
 */
public class Main {
    static int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    static int ans = 0;

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

    // 全排列函数
    public static void fun(int k) {
        // 先判断是否到达边界 check的逻辑可能不同,别的相同
        if (k == a.length) {
            int x1 = a[0] + a[1] + a[3] + a[5];
            int x2 = a[0] + a[2] + a[4] + a[8];
            int x3 = a[5] + a[6] + a[7] + a[8];
            if (x1 == x2 && x2 == x3) {
                ans++;
            }
        }

        // 然后进行全排列
        for (int i = k; i < a.length; i++) {
            {
                int t = a[i];
                a[i] = a[k];
                a[k] = t;
            }
            fun(k + 1);
            // 回溯
            {
                int t = a[i];
                a[i] = a[k];
                a[k] = t;
            }
        }
    }
}

承压计算

这道题目的思路就是从第一行开始遍历到最后一行,每一行遍历都将这个的值分给下一行的相同位置和此位置的下一个位置,最后对最后一行进行排序验证最小值是不是题目要求给的那个,由此输出最大值。但是值得要注意的是我们题目给定的最大值,无论如何都无法加到这个值,所以我们将输入的值乘以2的30次方来计算,最后得到的肯定是结果的倍数,约分就可以了。

魔方状态(太麻烦)

老师一上来就说这道题目不想讲,说代码量太大。。。我:无语~~

170多行代码,,,过了

取数位

此题不难,题意简单明了,就是让你取出一个整形数字的第n位,填空题,是用递归实现的,return f(x/10,k);。x肯定是变小的,所以除以10,k不变

最大公共子串

用DP来求,用一个二维数组来存放两个字符串,行列相等即上一个位置加一,a[i][j] = a[i-1][j-1] + 1;

日期问题

根据条件模拟即可,有点麻烦,需要判断的条件很多,注意细节

包子凑数(不会)

背包问题,有点难,不会。。。

分巧克力

考察枚举优化,此题用迭代暴力的话肯定会爆,所以用二分优化就可以了,这道题目比上一题简单很多

K倍区间

太麻烦,,没时间看了

18年省赛

第几天

水题

方格计数

圆的基本方程

双重for循环,四个象限,先只看第一象限,即i*i + j*j <= 1000*1000,满足这个条件的加一,最后将这个结果乘以4就可以了。

复数幂

大数运算,BigInteger和BigDecimal

测试次数

后补

递增三元组

三层循环暴力破

螺旋折线

后补

。。。。。剩下的部分日后有缘再续上吧~~明天加油!!!

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值