蓝桥算法省赛真题总结

🌸解题方法汇总(java B组省赛)(-1代表自己能力范围不会,直接跳过)

12345678910
第四届日期(API)、吉姆拉尔森公式暴力枚举暴力深搜递归、大数类逻辑模拟逻辑模拟暴力查找(类集框架)模拟过程全排列、逻辑判断、逻辑枚举的条件判断,枚举所有情况题意理解,思维的巧妙运用
第五届数学逻辑数学逻辑字符串、暴力模拟数学、奇偶数数学逻辑暴力枚举全排列、逻辑检查模拟过程深度优先、过程模拟搜索、记忆化递归-1
第六届简单数学计算暴力枚举暴力枚举模拟过程发现小技巧全排列数学规律递归模拟过程递归、动态规划、矩阵快速幂递归最多一万层
第七届数学规律暴力枚举暴力全排列组合,规律递归、组合暴力、全排列组合、深搜、图、联通分量首先暴力、暴力优化(四层到两层)哈希递归模拟过程、细节很重要-1
第八届Excel、耐心敲代码计算、暴力计算器、全排列二维数组找规律-1过程模拟分析动态规划API、日期的细心判断(主要是细心找到每一个满足的条件)动态规划、扩展欧几里得、完全背包数学规律、模拟过程暴力、前缀和优化、取模运算
第九届日期、计算器(注意加一天)暴力计算、勾股定理大数类、数很大输入到文件动态规划、递归、二分随机快速排序、递归暴力、优化(二分)、(双指针)画图、画过程模拟、找出数学规律、等差数列求和、绝对值的消去面向对象的思维模拟、类的自定义排序、思维逻辑的严密性暴力深搜、DFS查找联通分量的个数-1(乘法逆元)
第十届综合分析、求最大值暴力求子串、Set集合暴力求值、有坑(只需要关注数的后四位,不然数字太大存不了)暴力分解、条件判断求最短路径、广度优先、深度优先、节点判断暴力破解模拟过程、注意合理运用变量和数组,利用二维数组和多个一维数组可以代替复杂的数据结构逻辑分析与严密性、字符串正则以及API的使用逻辑思维的分析与严密性、需要去考虑繁杂的所有可能的情况然后写出结果-1
第十一届手工计算、代码计算时注意减法时的边界不能减到负数日期、计算器、日期类数学求最值、求算数不等式相等时的边界情况-1(找规律,用代码去模拟题目要求程序计算的过程)动态规划、找出存放规律与状态的转移方程暴力取模、优化(位运算>>取代 / )(即n = n>> 1 相当于 n = n / 2)熟练使用API、StringBuilder以及字符串的判断、总的来说就是暴力模拟深度优先搜索、动态规划暴力拼接(双重for)、优化(二维数组、位数取取余等)-1
第十二届暴力查找深度优先数学找规律数学组合(暴力组合和深搜)暴力尝试保留两位小数以及四舍五入

🌸黄金分割数与斐波那契数列的关系

比较简单的一种是用连分数:
                                   1
    黄金数 = ------------------------------
                                     1
                    1 + ---------------------
                                        1
                           1 + -------------
                                          1
                                 1 + -------
                                       1 + ...
                         
    这个连分数计算的“层数”越多,它的值越接近黄金分割数。
    请你利用这一特性,求出黄金分割数的足够精确值,要求四舍五入到小数点后100位。
    小数点后3位的值为:0.618
    小数点后4位的值为:0.6180
    小数点后5位的值为:0.61803
    小数点后7位的值为:0.6180340

可以分析得出

第二层      1/2    后两位
第三层      2/3    后三位
第四层      3/5	后四位
第五层      5/8	后五位
.....
以此类推
即后100位为稳定的100多位的斐波那契数相除,则可以得出代码
import java.math.BigDecimal;
import java.math.BigInteger;

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 divide = new BigDecimal(a, 110).divide(new BigDecimal(b, 110), BigDecimal.ROUND_HALF_DOWN);
        System.out.println(divide.toPlainString().substring(0, 103));
	
	}
    //求斐波那契
    static BigDecimal fb(int n){
        BigDecimal a = BigDecimal.ONE;
        BigDecimal b = BigDecimal.ONE;
        for (int i = 0; i < n; i++) {
            BigDecimal t = b;
            b = a.add(b);
            a=t;
        }
        return b;
    }
}

🌸圆周率与连分数

    4                               1
   ----   = 1 +  ------------------------------
    N(圆周率)                            9
                    1 + ---------------------
                                          25
                           2 + -----------------
                                            
                                 2 + .............
                                      
                                      
double x = 111; 
    for(int n = 10000; n>=0; n--){
        int i = 2 * n + 1;
        x = 2 + (i*i / x);
    }
   
    System.out.println(String.format("%.4f", 4/ (x - 1)));

🌸吉姆拉尔森公式

	private static int whatday(int y, int m, int d) {
		if(m == 1) {
			y--;
			m = 13;
		}
		if(m == 2) {
			y--;
			m = 14;
		}
		return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
	}

🌸复数幂(复数的阶乘)(了解打印流的使用文本)

复数计算的规律 尝试用 (a+bi)(c+di) = (ac - bd) + (ad + b*c)i

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.math.BigInteger;

public class Main {
	public static void main(String[] args) throws FileNotFoundException {
		//System.out.println(getNum(new BigInteger("2"), new BigInteger("3"), new BigInteger("2"), new BigInteger("3")));
		
		BigInteger a = new BigInteger("2");
		BigInteger b = new BigInteger("3");
		BigInteger c = new BigInteger("2");
		BigInteger d = new BigInteger("3");
		int n = 1;
		BigInteger shi;
		BigInteger xu;
		
		while(n < 123456) {
			shi = a.multiply(c).subtract((b.multiply(d)));
			xu = a.multiply(d).add(b.multiply(c));
			n++;
			a = shi;
			b = xu;
		}
		
		if(b.compareTo(new BigInteger("0")) == 1) {
			System.out.println(a + "+" + b + "i");
		}else if(b.compareTo(new BigInteger("0")) == 0) {
			System.out.println(a + "");
		}else {
			System.out.println(a + "" + b + "i");
		}
		
		PrintStream out = System.out;
		PrintStream ps = new PrintStream(new File("ans.txt"));
		System.setOut(ps);;//输出在ans.txt
		System.out.println(a.toString() +b.toString() + "i");
		System.setOut(out);
		System.out.println(a.toString() + b.toString() + "i");
	}

🌸扔鸡蛋问题(摔手机)(面试题)(动态规划)

你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。

每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

你的目标是确切地知道 F 的值是多少。

无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?

class 鸡蛋解法力扣 {
    static Integer[][] memo = null;
    static public int superEggDrop(int K, int N) {
        memo = new Integer[K+1][N+1];
        return dp(K,N);
    }

    /**
     *当前K个鸡蛋共有N层楼状态时 返回这个状态下确定 F的值的最小移动次数
     */
    static private int dp(int k,int n){
        //base case 层数N等于0时不需要扔鸡蛋,当鸡蛋数K为1时,只能每层逐个尝试剩下所有楼层
        if(k==1)return n;
        if(n<=0)return 0;

        //添加一个备忘录 消除之前算过的重叠子问题
        if(memo[k][n]!=null)
            return memo[k][n];

        int tmp = Integer.MAX_VALUE;

         //第一种 从第1层楼到第n层楼每层楼开始逐个尝试作为切入点 (会超时)
         for(int i=1;i<=n+1;i++){
             //当选择在第i层楼扔了鸡蛋之后 可能出现鸡蛋碎了和鸡蛋没碎两种情况:
             //当鸡蛋碎了 问题状态转嫁为求k-1个鸡蛋 搜索的楼层区间变为1~i-1共i-1层楼时求解
             int eggBreak=dp(k-1,i-1);
             //当鸡蛋没碎 问题状态转嫁为鸡蛋的个数K不变 搜索楼层区间变为i+1~N共N-i层楼时求解
             int eggUnBreak=dp(k,n-i);
             //最终以i层为切入点求解的答案 为两种状态的最坏情况 并加上i层时操作1 并更新最小值
             tmp = Math.min(tmp,Math.max(eggBreak,eggUnBreak)+1);
         }

        //第二种 利用二分查找的方式直接找到对应点(AC通过)
        //第一种线性逐个尝试切入点 然后求每个切入点两种状态的较大值 再求这些最大值之中的最小值 其实就是求这两条单调递增和单调递减直线的交点 相当于求上半部V形山谷值 二分查找来快速寻找这个点
//        int lo=1,hi =n;
//        while(lo<=hi){
//            int mid =(lo+hi)/2;
//            int eggBreak = dp(k-1,mid-1);
//            int eggUnBreak = dp(k,n-mid);
//            if(eggBreak>eggUnBreak){
//                hi = mid-1;
//                tmp = Math.min(tmp,eggBreak+1);
//            }else{
//                lo = mid+1;
//                tmp = Math.min(tmp,eggUnBreak+1);
//            }
    //    }

        //添加到备忘录里
        memo[k][n]=tmp;
        //返回当前k个鸡蛋n层楼时求解的子问题的结果
        return tmp;
    }
    public static void main(String[] args) {
        System.out.println(dp(3,1000));
    }
}

x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。

各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。

如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。

特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。

如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n

为了减少测试次数,从每个厂家抽样3部手机参加测试。

某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

请填写这个最多测试次数。

public class Main{
 
    public static void main(String[] args) {
        for(int i=0;i<10;i++)
            for(int j=0;j<10000;j++)
                memo[i][j] = 99999999;//找最小,初始化INF
        System.out.println(f(3,1000));
        //f(k,n)  当前的鸡蛋数  k
        //        需要测试的楼层数  n
    }

    static int[][] memo = new int[10][10000];

    static int f(int k,int n) {
        if(k==1) //当鸡蛋数只有1时,只能线性扫描所有的楼层 n 有多少层就得扔多少次 注意题目条件是运气差。
            return n;

        if(n<=0) //当楼层数0是 没法扔鸡蛋
            return 0;

        if(memo[k][n]!=99999999)  //避免重复计算
            return memo[k][n];

        int result=99999999;
        for(int i=1;i<=n;i++) {  //穷举所有的可能选择
            //当选择在第i层楼扔了鸡蛋之后 可能出现鸡蛋碎了和鸡蛋没碎两种情况:
            //当鸡蛋碎了 问题状态转嫁为求k-1个鸡蛋 搜索的楼层区间变为1~i-1共i-1层楼时求解
            int eggBreak=f(k-1,i-1);
            //当鸡蛋没碎 问题状态转嫁为鸡蛋的个数K不变 搜索楼层区间变为i+1~N共N-i层楼时求解
            int eggUnBreak=f(k,n-i);
            //最终以i层为切入点求解的答案 为两种状态的最坏情况 并加上i层时操作1 并更新最小值

            result= Math.min(result,
                    Math.max(
                            eggBreak,eggUnBreak
                    )+1    //1表示在i层时要扔一次
            );

        }
        memo[k][n]=result;
        return memo[k][n];
    }
 
}

🌸日期类(SimpleDateFormat +Date)

public static class Main{
    public static void main(){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd");
        Date date1 = format.parse("1921-7-23");
        Date date2 = format.parse("2020- 7-1");
        int a = (int)((date2.getTime() - date1.getTime()) / 1000 * 60);//相隔多少分钟
    }
}
//直接使用 Date
public static class Main{
    public static void main(){
        long sum = 36138 * 24 * 60L;
        System.out.println(sum);
        System.out.println(36138 * 24 * 60);
        // long型变量在定义的时候,如果不加“L”,则默认为int型变量
        Date date1 = new Date(21, 7, 23, 12, 0, 0); // 1921
        Date date2 = new Date(120, 7, 1, 12, 0, 0); // 2020
        long time = date2.getTime() - date1.getTime();
        System.out.println(time / (60000));
    }
}

🍁未更新(待补充)

🍂 fff
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值