蓝桥杯--结束

news2025/5/19 2:28:09

冲刺题单

基础

一、简单模拟(循环数组日期进制)

(一)日期模拟

知识点

1.把月份写为数组,二月默认为28天。
2.写一个判断闰年的方法,然后循环年份的时候判断并更新二月的天数
3.对于星期数的计算:
int week = x;//x表示当前天数的星期数
week = week % 7 + 1;

1.艺术与蓝球–蓝桥19937

package datasimulation;

public class Test5 {
    //每个月,2月先默认为28天
    //数组下标从0开始,给monts【0】赋值0
    static int[] months = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    //汉字笔画数
    static int[] hz = {13, 1, 2, 3, 5, 4, 4, 2, 2, 2};

    //判断闰年
    static boolean isLeapYear(int year){
        //能整除400 或者 能整除4不能整除100
        return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
    }

    static void solve(){
        int ans = 0;//记录打篮球的天数

        for(int y = 2000; y <= 2024; y++){
            //重判二月的天数
            months[2] = isLeapYear(y) ? 29 : 28;
            for(int m = 1; m <= 12; m++){
                for(int d = 1; d <= months[m]; d++){
                    int sum = 0;//记录权值
                    //获得每一个数
                    int y1 = y / 1000;
                    int y2 = y / 100 % 10;
                    int y3 = y / 10 % 10;
                    int y4 = y % 10;
                    int m1 = m / 10;
                    int m2 = m % 10;
                    int d1 = d / 10;
                    int d2 = d % 10;

                    sum = hz[y1] + hz[y2] + hz[y3] + hz[y4]
                            + hz[m1] + hz[m2]
                            +hz[d1] + hz[d2];

                    //判断权值
                    if(sum > 50) ans++;

                    //循环结束条件
                    if(y == 2024 && m == 4 && d == 13){
                        System.out.println(ans);
                        return;//结束
                    }


                }
            }
        }
    }

    public static void main(String[] args) {
        solve();
    }
}
//答案:3228

2.岁月流转–星期模拟–蓝桥16955

本题就和上面一样,不过多了个星期的问题,应用那两条公式即可。
package datasimulation;

public class Test6 {
    //每个月,2月先默认为28天
    //数组下标从0开始,给monts【0】赋值0
    static int[] months = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    //判断闰年
    static boolean isLeapYear(int year){
        //能整除400 或者 能整除4不能整除100
        return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
    }

    //获取1900年12月31日的星期数
    static int getWeek(int week){
        //1900年1.1是星期一,那么它前一天是星期日即7
        months[2] = isLeapYear(1900) ? 29 : 28;
        for (int m = 1; m <= 12; m++) {
            for (int d = 1; d <= months[m]; d++) {
                week = week % 7 + 1;
            }
        }
        return week;
    }

    static void solve(){
       int week = getWeek(7);获取1900年12月31日的星期数
        int ans = 0;
        for (int y = 1901; y <= 2000; y++) {
            months[2] = isLeapYear(y) ? 29 : 28;
            for (int m = 1; m <= 12; m++) {
                for (int d = 1; d <= months[m]; d++) {
                    week = week % 7 + 1;
                    if(d == 1 && week == 7) ans++;
                }
            }
        }
        System.out.println(ans);
    }

    public static void main(String[] args) {
        solve();
    }
}
//171

3.跑步计划–日期星期模拟–蓝桥17113


public class Main {
    //每个月,2月先默认为28天
    //数组下标从0开始,给monts【0】赋值0
    static int[] months = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    //判断闰年
    static boolean isLeapYear(int year){
        //能整除400 或者 能整除4不能整除100
        return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
    }

    static void solve(){
        int kl = 0;//跑步的公里数
        //2023.1.1是星期日
        int week = 6;
        months[2] = isLeapYear(2023) ? 29 : 28;
        for (int m = 1; m <= 12; m++) {
            for (int d = 1; d <= months[m]; d++) {
                //计算星期
                week = week % 7 + 1;
                //拆分数字
                int m1 = m / 10;
                int m2 = m % 10;
                int d1 = d / 10;
                int d2 = d % 10;

                //只要年月日或者星期有1,就跑5千米
                if(week == 1 || m1 == 1 || m2 == 1 || d1 == 1 || d2 == 1){
                    kl += 5;
                }else{
                    kl += 1;
                }
            }
        }
        //输出公里数
        System.out.println(kl);
    }

    public static void main(String[] args) {
        solve();
    }
}
//1333

4.一年中的第几天–蓝桥1935

package datasimulation;

import java.util.Scanner;

public class Test8 {
    static int[] months = {0,31,28,31,30,31,30,31,31,30,31,30,31};

    //判断闰年
    static boolean isLeapYear(int y){
        return (y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0));
    }
    //主逻辑函数
    static void solve(int y, int m, int d){
        int day = 0;//表示第几天
        //更新2月的天数
        months[2] = isLeapYear(y) ? 29 : 28;
        for (int i = 1; i <= 12; i++) {//月份数
            for (int j = 1; j <= months[i]; j++) {//天数
                day++;
                if(i == m && j == d){
                    System.out.println(day);
                    return;//结束循环
                }
            }
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(true){
            int y = sc.nextInt();
            int m = sc.nextInt();
            int d = sc.nextInt();

            if(y == 0 && m == 0 && d == 0) break;//结束

            solve(y, m, d);
        }
    }
}

本题出现评测机段错误的原因:
将Scanner写在了while循环中,拿出来即可
因此获得经验:对于一些特定的语句,一定要注意只创建一次即可。

5.回文日期–蓝桥498

注意给定的N小于89991231但是循环的边界不应该是8999,而应该是9999
package datasimulation;

import java.util.Scanner;

public class Test9 {
    static boolean flag1 = false;
    static boolean flag2 = false;
    static int[] months = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    //判断闰年
    static boolean isLeapYear(int y) {
        return (y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0));
    }

    static boolean check(int y, int m, int d) {
        //获得每一位数
        int y1 = y / 1000;
        int y2 = y / 100 % 10;
        int y3 = y / 10 % 10;
        int y4 = y % 10;
        int m1 = m / 10;
        int m2 = m % 10;
        int d1 = d / 10;
        int d2 = d % 10;
        //判断回文
        if (flag1 == false) {
            if (d2 == y1 && d1 == y2 && m2 == y3 && m1 == y4) {
                flag1 = true;
                if(m >= 10 && d >= 10){
                    System.out.println(y + "" + m + "" + d);
                } else if (m >= 10 && d < 10) {
                    System.out.println(y + "" + m + "0" + d);
                } else if (d >= 10 && m < 10) {
                    System.out.println(y + "0" + m + "" + d);
                } else if (m < 10 && d < 10) {
                    System.out.println(y + "0" + m + "0" + d);
                }
            }
        }
        //判断ABABBABA型回文
        int A = y1;
        int B = y2;
        if (flag2 == false) {
            if (y3 == A && y4 == B && m1 == B && m2 == A && d1 == B && d2 == A) {
                flag2 = true;
                if(m >= 10 && d >= 10){
                    System.out.println(y + "" + m + "" + d);
                } else if (m >= 10 && d < 10) {
                    System.out.println(y + "" + m + "0" + d);
                } else if (d >= 10 && m < 10) {
                    System.out.println(y + "0" + m + "" + d);
                } else if (m < 10 && d < 10) {
                    System.out.println(y + "0" + m + "0" + d);
                }
            }
        }

            //两个都判断结束退出
            if (flag1 && flag2) {
                return true;
            }

            return false;
        }

            static void solve () {

                Scanner sc = new Scanner(System.in);
                int N = sc.nextInt();

                int year = N / 10000;
                int month = N / 100 % 100;
                int day = N % 100;

                //先循环到这个月结束
                months[2] = isLeapYear(year) ? 29 : 28;
                for (int d = day + 1; d <= months[month]; d++) {
                    boolean f = check(year, month, d);
                    if(f){
                        return;//结束循环
                    }
                }


                //循环到这一年结束
                months[2] = isLeapYear(year) ? 29 : 28;
                for (int m = month + 1; m <= 12; m++) {
                    for (int d = 1; d <= months[m]; d++) {
                        boolean f = check(year, m, d );
                        if(f){
                            return;//结束循环
                        }
                    }
                }


                for (int y = year + 1; y <= 9999; y++) {
                    months[2] = isLeapYear(y) ? 29 : 28;
                    for (int m = 1; m <= 12; m++) {
                        for (int d = 1; d <= months[m]; d++) {
                            boolean f = check(y, m, d );
                            if(f){
                                return;//结束循环
                            }
                        }

                    }
                }
            }

        public static void main (String[]args){
            solve();
        }
    }



更简便的写法:
data等的使用

6.神奇的闹钟–蓝桥19730


(二)进制转换

知识点

1.1K进制转十进制

K进制转十进制:
对于十六进制,由于它的数字表示范围为0-9,A-Z(或者a-z),在转换时要注意。
因此在赋值存储时,将要转换的进制数使用字符串类型来存储。
由此在进行进制转换前,要先将字符串类型的进制数转为数字。
1.将字符转换为数字值:
利用ascii码来进行转换。
2.将进制数转换为十进制:
horner法则

image-20250303080647318

模板

package jinzhizhuanhuan;

public class Test1 {
    //将字符转为数字
    static int calc(char c){
        //大于10的数
        if(c >= 'a'){//A或者a看题目要求
            return 10 + (c - 'a');
        }else {
            return (c - '0');
        }
    }
    //将给定的字符串转换为10进制
    static int change(int k, String s){
        int ans = 0;
        for (int i = 0; i < s.length(); i++) {
            ans = ans * k + calc(s.charAt(i));
        }
        return ans;
    }
    public static void main(String[] args) {
        System.out.println( change(16,"4e"));//78
    }
}

题目答案

package jinzhizhuanhuan;
import java.util.Scanner;
public class Test6 {
    //得到位数
    static int calc(char c){
        if(c >= 'A'){
            return 10 + (c - 'A');
        }else{
            return c - '0';
        }
    }
    //k进制转10进制
    //幂运算转为hornor运算
    static int change(int k, String s){
        int ans = 0;

        for (int i = 0; i < s.length(); i++) {
            ans = ans * k + calc(s.charAt(i));
        }
        return ans;
    }

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

        int x = sc.nextInt();
        String s = sc.next();

        System.out.println(change(x, s));
    }
}

1.2十进制转K进制–洛谷B3619

**除K取余法**
注意得到所有的余数后要反向排列才是最后的结果。

模板

package jinzhizhuanhuan;

public class Test2 {
    static String change(int x, int k){
        //把x转为k进制
        StringBuffer ans = new StringBuffer();
        while(x != 0){
            int t = x % k;//除k取余
            if(t <= 9){//数字部分直接添加
                ans.append((char)('0' + t));
            }else{//字母部分从A开始
                ans.append((char)('A' + (t - 10)));
            }
            x = x / k;//更新x
        }
        //除K取余后要记得反转
        return ans.reverse().toString();
    }
    //十进制转K进制
    static void solve(){
        System.out.println(change(78, 16));
    }
    public static void main(String[] args) {
        solve();
    }
}

题目答案

import java.util.Scanner;
public class Main {

    static String change(int x, int k){
        //除K取余法
        StringBuffer ans = new StringBuffer();

        while(x != 0){
            int t = x % k;//除k取余
            if(t > 9){
                //字母部分
                ans.append((char)('A' + (t - 10)));
            }else{
                //数字部分
                ans.append((char)('0' + t));
            }
            x = x / k;//更新x
        }
        //除k取余得到的是一个反向的
        //最后要把它倒回来
        return ans.reverse().toString();
    }

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

        int n = sc.nextInt();
        int x = sc.nextInt();

        System.out.println(change(n, x));
    }
}

2.穿越时空之门–蓝桥19701

在上面的基础上进行修改即可
还无需考虑16进制的字母
package jinzhizhuanhuan;

public class Test3 {
    //十进制转K进制(不用担心十六进制的字母问题)
    //除k取余法并求各位数之和
    static int change(int x, int k){
        int ans = 0;//记录各位数之和
        while(x != 0){
            int t = x % k;//除k取余,k的取值是2和4,那么t的取值小于等于4
            ans += t;
            x = x / k;//更新x
        }
        return ans;
    }

    //主逻辑函数
    static void solve(){
        int count = 0;
        for (int i = 1; i <= 2024; i++) {
            if(change(i, 2) == change(i, 4))
                count++;
        }
        System.out.println(count);
    }
    public static void main(String[] args) {
        solve();
    }
}

3.九进制转十进制–蓝桥2095

就是前面模板直接套用就可以
package jinzhizhuanhuan;

public class Test4 {
    static int calc(char c){
        if(c >= 'A'){
            return 10 + (c - 'A');
        }else {
            //数字
            return c - '0';
        }
    }
    static int change(int k,String s){
        int ans = 0;
        //k进制转10进制
        //幂运算转换为hornor法则
        for (int i = 0; i < s.length(); i++) {
            ans = ans * k + calc(s.charAt(i));
        }
        return ans;
    }
    public static void main(String[] args) {
        System.out.println(change(9, "2022"));
    }
}

(三)枚举

1.好数–蓝桥19709

package meiju;

import java.util.Scanner;

public class Test1 {
    static boolean check(int x){
        int count = 1;//记录奇偶位数
        while(x != 0){
            int t = x % 10;
            if(count % 2 != 0){//奇数位上不能是偶数
                if(t % 2 == 0){
                    return false;
                }
            }
            if(count % 2 == 0){//偶数位上不能是奇数
                if(t % 2 != 0){
                    return false;
                }
            }
            x = x / 10;//更新,即去掉最后一位
            count++;//更新奇偶数位
        }
        //循环结束即是好数
        return true;
    }
    static void solve(){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();

        int ans = 0;//记录个数
        for (int i = 1; i <= n; i++) {
            if(check(i)){
                ans++;
            }
        }
        System.out.println(ans);
    }
    public static void main(String[] args) {
        solve();
    }
}

2.偶串–蓝桥17144

主要涉及HashMap的使用
import java.util.HashMap;
import java.util.Scanner;
public class Main {
    static int N = 1000010;
    //定义一个字符数组
    static HashMap<Character, Integer> charArr = new HashMap<Character, Integer>();

    //判断是否都为偶数
    static boolean check(HashMap<Character, Integer> arr){
        for (int count : charArr.values()) {
            if (count % 2 != 0) return false;//奇数返回错
        }
        return true;
    }

    static void solve(){
        Scanner sc = new Scanner(System.in);
        String s = sc.next();

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            //如果这个字符 c 已经存在,就获取它的计数,否则默认是 0。
            charArr.put(c, charArr.getOrDefault(c, 0) + 1);
        }

        if(check(charArr)){
            System.out.println("YES");
        }else{
            System.out.println("NO");
        }

    }
    public static void main(String[] args) {
        solve();
    }
}

3.幸运数–蓝桥3491

填空题,代码是超时的。。。
import java.util.ArrayList;

public class Main {
    // static int N = 15;//多一点防止奇怪的问题

    // static boolean check(int x){
    //     ArrayList<Integer> numArr = new ArrayList<>();
    //     int count = 0;//记录x的位数
    //     while(x != 0){
    //         int t = x % 10;//获得最后一位
    //         numArr.add(t);//添加到list中,下标从0开始
    //         x = x / 10;//舍弃最后一位
    //         count++;
    //     }
    //     //先判断是不是偶数位
    //     if(count % 2 != 0){
    //         return false;
    //     }
    //     //是偶数位
    //     int mid = count / 2;
    //     int sum1 = 0;
    //     int sum2 = 0;
    //     for (int i = 0; i < mid; i++) {
    //         sum1 += numArr.get(i);
    //     }
    //     for (int i = mid; i < count; i++) {
    //         sum2 += numArr.get(i);
    //     }

    //     //判断前后是否相等
    //     if (sum1 != sum2){
    //         return false;
    //     }

    //     //最后是偶数位,前后相等
    //     return true;
    // }

    // static void solve(){
    //     int ans = 0;
    //2位
    //     for (int i = 1; i <= 100; i++) {
    //         if(check(i)) ans++;
    //     }
    //4位
    //     for (int i = 1000; i <= 9999; i++) {
    //         if(check(i)) ans++;
    //     }
    //6位
    //     for (int i = 100000; i <= 999999; i++) {
    //         if(check(i)) ans++;
    //     }
    //8位
    //     for (int i = 10000000; i <= 99999999; i++) {
    //         if(check(i)) ans++;
    //     }



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

4.求和–蓝桥3493

简单的题目要特别注意数值范围和超时。
package meiju;

public class Test4 {
    public static void main(String[] args) {
        long ans = 0;
        for (int i = 1; i <= 20230408; i++) {
            ans += i;
        }
        System.out.println(ans);
    }
}

5.不完整的算式–蓝桥17135

特别注意中英文符号
四种情况:又可大概分为2种
首先判断字符串中是否有+-*/
一、有,找到加减乘除的位置op
1.A被擦掉
0的位置是?,那么A被擦掉
获得B=substring(op,=)
获得C=subString(=)
2.B
op后面的位置是?,那么B被擦掉
获得A=substring(0,op)
获得C=subString(=)
3.C
=后面的位置是?,C被擦掉
获得A=substring(0,op)
获得B=substring(op,=)
二、没有
4.op
找到?的位置,截取出A,B,C即可
package com.mj;
import java.util.Scanner;

public class Main{
	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		String s = sc.next();//输入等式
		
		//首先判断等式中有无四则运算符号
		//注意要依次判断
		int haveOp = s.indexOf('+');
		if(haveOp == -1) {
			haveOp = s.indexOf('-');
		}
		if(haveOp == -1) {
			haveOp = s.indexOf('*');
		}
		if(haveOp == -1) {
			haveOp = s.indexOf('/');
		}
		
		
		
		//没有,那么获得A,B,C的值
		 if(haveOp == -1) {
			 int op = s.indexOf('?');//op的位置
			 int d = s.indexOf('=');
			 //注意substring包前不包后
			 int A = Integer.parseInt(s.substring(0,op));
			 int B = Integer.parseInt(s.substring(op + 1,d));
			 int C = Integer.parseInt(s.substring(d + 1));
			 
			 if(A + B == C) {
				 System.out.println('+');
			 }else if(A - B == C) {
				 System.out.println('-');
			 }else if(A * B == C) {
				 System.out.println('*');
			 }else if(A / B == C) {
				 System.out.println('/');
			 }
			 
			 return;
			 
		 }
		
		 //有
		
		//A被擦掉
		if(s.charAt(0) == '?') {
			int d = s.indexOf('=');
			int B = Integer.parseInt(s.substring(haveOp + 1, d));
			int C = Integer.parseInt(s.substring(d + 1));
			if(s.charAt(haveOp) == '+') {
				System.out.println(C - B);
			}else if(s.charAt(haveOp) == '-') {
				System.out.println(C + B);
			}else if(s.charAt(haveOp) == '*') {
				System.out.println(C / B);
			}else if(s.charAt(haveOp) == '/') {
				System.out.println(C * B);
			}
			
			return;
		}
		//B被擦掉
		if(s.charAt(haveOp + 1) == '?') {
			int d = s.indexOf('=');
			int A = Integer.parseInt(s.substring(0, haveOp));
			int C = Integer.parseInt(s.substring(d + 1));
			if(s.charAt(haveOp) == '+') {
				System.out.println(C - A);
			}else if(s.charAt(haveOp) == '-') {
				System.out.println(A - C);
			}else if(s.charAt(haveOp) == '*') {
				System.out.println(C / A);
			}else if(s.charAt(haveOp) == '/') {
				System.out.println(A / C);
			}
			
			return;
		}
		//C被擦掉
		int d = s.indexOf('=');
		int A = Integer.parseInt(s.substring(0, haveOp));
		int B = Integer.parseInt(s.substring(haveOp + 1, d));
		if(s.charAt(haveOp) == '+') {
			System.out.println(A + B);
		}else if(s.charAt(haveOp) == '-') {
			System.out.println(A - B);
		}else if(s.charAt(haveOp) == '*') {
			System.out.println(A * B);
		}else if(s.charAt(haveOp) == '/') {
			System.out.println(A / B);
		}
		
	}
    public static void main(String[] args){
    	solve();
    }
}

(四)自定义排序

知识点

1.排序:
Arrays.sort 的自定义排序器只接受对象数组。使用整型对象数组(Integer[])
Arrays.sort(数组)
Arrays.sort(数组,开始,结束)//包前不包后
2.自定义比较器:
不理解

自定义排序注意点-CSDN博客

image-20250411104100681

你用的是什么排序方法要求的类型
int[]Arrays.sort(arr)无法使用 Comparator
Integer[]Arrays.sort(arr, cmp)✅ 可以使用 Comparator
ArrayList<T>Collections.sort(list, cmp)✅ 正确

模板

import java.util.Arrays;
import java.util.Comparator;
public class Main {
// 1. 普通数组排序
static Integer[] nums = {3,1,4,1,5,9};
// 2. 对象排序
static class Student {
String name;
int score;
Student(String name, int score) {
this.name = name;
this.score = score;
}
}
public static void main(String[] args) {
// 匿名内部类方式
Arrays.sort(nums, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b - a; // 降序
}
});
// 学生数组
Student[] students = {new Student("Alice",90), new
Student("Bob",85)};
// 多级排序
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student a, Student b) {
if(a.score != b.score)
return b.score - a.score; // 分数降序
return a.name.compareTo(b.name); // 姓名升序
}
});
}
}

1.区间排序

https://www.luogu.com.cn/problem/B4041

注意l和r是从1开始得
而数组下标是从0开始的
package com.mj;
import java.util.*;

public class Main{
//	static int N = 100010;
	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
	    Integer[] a = new Integer[n];
	    
		for(int i =  0; i < n; i++) {
			a[i] = sc.nextInt();
		}
		
		int q = sc.nextInt();
		
		while(q != 0) {
			int l = sc.nextInt() - 1;
			int r = sc.nextInt() - 1;
			//包前不包后
			Arrays.sort(a, l, r + 1);
			q--;
		}
		
		
		for(int i =  0; i < n; i++) {
			System.out.print(a[i] + " ");
		}
		
		
	}
    public static void main(String[] args){
    	solve();
    }
}

2.奇偶排序

https://hydro.ac/d/shallowdream/p/38

对数组进行排序
自定义比较器:
判断奇偶性:
不同:偶数大于奇数
相同:实际数值大小比较
package com.mj;
import java.util.*;

public class Main{
//	static int N = 100010;
	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		
		
		int n = sc.nextInt();
	    Integer[] num = new Integer[n];
		for(int i =  0; i < n; i++) {
			num[i] = sc.nextInt();
		}
		
		Arrays.sort(num, new Comparator<Integer>() {
			public int compare(Integer a, Integer b) {
				//判断奇偶性:
				//不同:偶数大于奇数
				//相同:实际数值大小比较
				if(a % 2 == b % 2) {
					//奇偶性相同,实际数值,由小到大
					return a - b;
				}else {
					//不同:偶数大于奇数
					//a是偶数,返回1,a大于b排后面
					//a是奇数,返回-1,a小于b排前面
					return (a % 2 == 0) ? 1 : -1;
				}
			}
			
		});
		
		//
		for(int i =  0; i < n; i++) {
			System.out.print(num[i] + " ");
		}
		
		
	}
    public static void main(String[] args){
    	solve();
    }
}
注意:最开始在外面创建数组,创建得很大
而排序是对整个数组进行排序
因此报空指针错误
所以要在里面进行一个创建数组并排序。
还要特别注意,普通数组不能自定义排序
Integer数组对应Arrays.sort
ArrayList数组对应Collections.sort

3.平面最近点对:

https://hydro.ac/d/shallowdream/p/37


package com.mj;
import java.util.*;

public class Main{
	
	static class zuobiao{
		int x;
		int y;
		zuobiao(int x,int y){
			this.x = x;
			this.y = y;
		}
	}

	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
		zuobiao[] arr = new zuobiao[n];//创建对象数组
	    
		for(int i =  0; i < n; i++) {
			int x = sc.nextInt();
			int y = sc.nextInt();
			zuobiao t = new zuobiao(x,y);
			arr[i] = t;
		}
		
		//自定义排序
		Arrays.sort(arr, new Comparator<zuobiao>() {
			public int compare(zuobiao a, zuobiao b) {
				int x1 = a.x;
				int y1 = a.y;
				int x2 = b.x;
				int y2 = b.y;
				
				//先判断欧几里得距离
				long s1 = (long)x1 * x1 + (long)y1 * y1;
				long s2 = (long)x2 * x2 + (long)y2 * y2;
				if(s1 != s2) {
					if(s1 < s2) {
						//降序排序,先排a
						return -1;
					}else {
						return 1;
					}
				}
				
				//再判断横坐标
				if(x1 != x2) {
					if(x1 < x2) {
						return -1;//先排a
					}else {
						return 1;
					}
				}
				
				//再判断纵坐标
				//前面都没有才会运行此处,不if不然没有返回值
//				if(y1 != y2) {
					if(y1 < y2) {
						return -1;//先排a
					}else {
						return 1;
					}
				}

			
		});
		
		//输出
		for(int i =  0; i < n; i++) {
			System.out.println(arr[i].x + " " + arr[i].y);
		}
		
	}
    public static void main(String[] args){
    	solve();
    }
}
虽然逻辑没有问题,但是超时了,超时的原因是输入使用Scanner。
所以修改如下。
//改用 BufferedReader + StringTokenizer
package com.mj;
import java.io.*;
import java.util.*;

public class Main {

    static class Point {
        int x, y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    public static void main(String[] args) throws IOException {
        // 快速输入
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        Point[] arr = new Point[n];

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            arr[i] = new Point(x, y);
        }

        // 排序
        Arrays.sort(arr, new Comparator<Point>() {
            public int compare(Point a, Point b) {
                long d1 = 1L * a.x * a.x + 1L * a.y * a.y;
                long d2 = 1L * b.x * b.x + 1L * b.y * b.y;
                if (d1 != d2) return Long.compare(d1, d2);
                if (a.x != b.x) return Integer.compare(a.x, b.x);
                return Integer.compare(a.y, b.y);
            }
        });

        // 快速输出
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        for (int i = 0; i < n; i++) {
            bw.write(arr[i].x + " " + arr[i].y + "\n");
        }
        bw.flush(); // 一定要刷新
    }
}

4.三国游戏:

https://www.lanqiao.cn/problems/3518/learning

5.拼数:

https://www.luogu.com.cn/problem/P1012

(四)自定义排序

1.蓝桥19723–分布式队列

package datasimulation;

import java.util.Scanner;

public class Test3 {
    //计算数组中最小值
    public static int getMin(int[] arr){
        int min = arr[0];//最好设为数组中的某个值
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] < min){
                min = arr[i];
            }
        }
        return min;
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入N
        int N = sc.nextInt();
        //创建一个长度为N的数组,数组元素表示的是每个节点数组的长度
        int[] arr = new int[N];
        //输入?行数据
        while(sc.hasNext()){
            String op = sc.next();
            if(op.equals("add")){
                int opNum = sc.nextInt();
                //主节点数组长度加1
                arr[0]++;
            } else if (op.equals("sync")) {
                int opNum = sc.nextInt();
                //副节点数组长度加1
                //!!!特别注意!!!
                副队列同步主队列,如果在执行这次操作时副队列已经是跟主队列相同了,
                // 此时再加1并不合理,最高就是跟主队列相同
                //其实题目的用例有偷偷暗示
                arr[opNum] = Math.min(arr[opNum] + 1,arr[0]);
            }else{
                //输出可见数
                //其实就是输出arr数组中的最小值--各个节点数组的长度最小值
                System.out.println(getMin(arr));
            }
        }

    }
    public static void main(String[] args) {
        solve();
    }
}

注意:
1.使用一个数组来描述,数组的元素表示的是每个节点数组的长度,可见数其实就是这个数组中最小的元素。
2.要特别注意观察题目给的样例,其中可能暗藏玄机。
最开始我只通过50%,后来才发现给的用例可能会重复,如果遇到sync只是一味加加,那么副节点数组的长度就会超过主节点,这就不对了。
3.学到了一个sc.hasNext()的使用。因为本题不知道输入的操作个数。
4.特别注意数据的输入格式。

2.蓝桥19709–好数

package datasimulation;

import java.util.Scanner;

public class Test4 {
    public static boolean check(int n){
        int count = 1;//表示奇偶数位
        int jicount = 0;
        int oucount = 0;
        while(n != 0){
            int t = n % 10;
            n = n / 10;
            if(count % 2 == 0 && t % 2 == 0){
                oucount++;
            }
            if(count % 2 != 0 && t % 2 != 0){
                jicount++;
            }
            count++;//下一位
        }
        //注意上面循环count多加了1
        if(jicount + oucount + 1 == count)  return true;
        else return false;
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入N
        int N = sc.nextInt();
        int count = 0;//记录好数
        for (int i = 1; i <= N; i++) {
            if(check(i)) count++;
        }
        System.out.println(count);
    }
    public static void main(String[] args) {
        solve();
    }
}

//判断好数
    //奇数位不能是偶数,偶数位不能是奇数
    public static boolean check(int n){
        int cnt = 1;//位数计数器
        while(n != 0){
            int t = n % 10;
            if(cnt % 2 != 0){
                //奇数位不能偶数
                if(t % 2 == 0) return false;
            }
            if(cnt % 2 == 0){
                //偶数位不能是奇数
                if(t % 2 != 0) return false;
            }
            cnt++;//下一位数
            n = n / 10;
        }
        return true;//都结束了返回true
    }
学到的知识点:
本题使用暴力来做,额我就只想到对于奇数位是奇数的加1,偶数位是偶数的加一,因此要循环全部,效率较低。而且还有一点就是最好的count多加了1。
老师的解法就是奇数位偶数返回错,偶数位奇数返回错。这样提高了效率,也不需要注意太多。

二、前缀和与差分 要求:省二以上会

知识点

1.一维前缀和:s[i]=s[i-1]+a[i]
快速查询区间和。l-r的区间和就是s[r]-s[l-1]

2.一维差分:b[i]=a[i]-a[i-1]
差分数组求前缀和是原数组。
快速进行区间修改(加减)。对l-r的元素加上d,只要b[l]+=d,b[r+1]-=d即可。
以及重要的一点:判断序列元素是否相同,即差分数组除了第一项以外的项数均为0,那么原数组一定所有数字相同。

对于二维,画图更好理解

1.二维前缀和
规定的二维前缀和如下:从(1,1))开始到(x,y)所围成的一个子矩阵中的数的和
对于(x1,y1)到(x2,y2)围成的子矩阵的和,计算如下:
s(x2,y2)-x(x2,y1-1)-x(x1-1,y2)+x(x1-1,y1-1)
如何构造前缀和:
s(x,y)=a(x,y)+s(x-1,y)+s(x,y-1)-s(x-1,y-1)
2.二维差分
**前缀和数组求差分后是原数组,原数组求差分后是差分数组。**
**差分数组求前缀和是原数组,原数组求前缀和是前缀和数组。**
一定明确差分数组求前缀和是原数组。
对差分数组b[i][j]求前缀和,
而差分数组求前缀和就是原数组a[i][j],
所以套用前缀和公式,有:
a[i][j]=b[i][j]+a[i][j-1]+a[i-1][j]-a[i-1][j-1]
对其进行移项,就得到差分数组的公式:
b[i][j]=a[i][j]-a[i][j-1]-a[i-1][j]+a[i-1][j-1]
对一个差分数组,对其x1,y1进行修改,相当于对原数组x1,y1到右下角进行修改
b[x1][y1] += d;
b[x2 + 1][y1] -= d;
b[x1][y2+1] -= d;
b[x2+1][y2+1] += d;

1.1蓝桥18437–一维前缀和(模板

主要注意数据的范围,计算极端情况下数据的范围是否超过int。
package com.mj;
import java.util.Scanner;

public class Main{
	static int N = 100010;
	static int n,q;
	static int[] a = new int[N];
	static int[] s = new int[N];//前缀和数组
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		q = sc.nextInt();
		for(int i = 1; i <= n; i++) {
			a[i] = sc.nextInt();
			//计算前缀和数组
			s[i] = s[i - 1] + a[i];
		}
		//q组查询
		for(int i = 0; i < q; i++) {
			int l = sc.nextInt();
			int r = sc.nextInt();
			System.out.println(s[r] - s[l - 1]);
		}
	}
    public static void main(String[] args){
    	solve();
    }
}

1.2.求和-蓝桥2080

其实也差不多是一道模板题目的变形。但这题就要注意数值范围了,有一个需要为long,其它不知道怎么搞那就都为long吧。防止溢出之类的。
找规律,提取公因数,最终得到每项都是
a[i]*(a[i+1] + …… + a[n])

1.3一维差分–模板–蓝桥18438

模板提。注意数值范围即可。
还要注意输出的格式。
package com.mj;
import java.util.Scanner;

public class Main{
	static int N = 200010;
	static int n,m;
	static int[] a = new int[N];
	static int[] b = new int[N];//差分数组
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		
		for(int i = 1; i <= n; i++) {
			a[i] = sc.nextInt();
			//计算差分数组
			b[i] = a[i] - a[i - 1];
		}
		
		for(int i = 0; i < m; i ++) {
			int l = sc.nextInt();
			int r = sc.nextInt();
			int d = sc.nextInt();
			//对l-r的数增加d
			b[l] += d;
			b[r + 1] -= d;
		}
		
		//对差分数组求前缀和得到原数组
		for(int i = 1; i <= n; i++) {
			a[i] = a[i - 1] + b[i];
			System.out.print(a[i] +" ");
		}
		
	}
    public static void main(String[] args){
    	solve();
    }
}

1.4小蓝的操作–利用差分数组判断序列元素是否相等–蓝桥3399

本题主要还是思维的问题。要将操作的问题进行一个转换。
因为是选择区间进行减一操作,且数据保证一定有解。
那么对于差分数组而言,要让除了第一项外的大于0的数都为0,第一项为1。
把这些数加起来就是操作数。

注意数值范围:
分析3:数值范围的分析
对于差分数组,若原数组最坏情况下为1 100000 1 100000这么排列,那么差分数组可能有一半的数量为99999,那么n的一半为5*10^4,相乘大于4.5*10^9,大于int的范围。所以ans需要为long类型。
package com.mj;
import java.util.Scanner;

public class Main{
	static int N = 100010;
	static int n;
	static long[] a = new long[N];
	static long[] b = new long[N];//差分数组
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		
		for(int i = 1; i <= n; i++) {
			a[i] = sc.nextInt();
			//计算差分数组
			b[i] = a[i] - a[i - 1];
		}
		
		long ans = 0;//操作数
		//差分数组第一项为1
		ans = b[1] - 1;//第一项操作几次变为1
		for(int i = 2; i <= n; i++) {
			if(b[i] > 0) {
				ans += b[i];//b[i]操作几次变为0
			}
		}
		System.out.print(ans);
		
	}
    public static void main(String[] args){
    	solve();
    }
}

1.5二维前缀和–模板–蓝桥18439

模板提。
主要判断数值范围。
package com.mj;
import java.util.Scanner;

public class Main{
	static int N = 1010;
	static int n,m,q;
	static int[][] a = new int[N][N];
	static int[][] s = new int[N][N];//前缀和数组
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		q = sc.nextInt();
		//输入数组
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				a[i][j] = sc.nextInt();
				//计算前缀和
				s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
			}
		}
		
		//q组查询
		for(int i = 0; i < q; i++) {
			int x1 = sc.nextInt();
			int y1 = sc.nextInt();
			int x2 = sc.nextInt();
			int y2 = sc.nextInt();
			System.out.println(s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 -1][y1 -1]);
		}
		
	}
    public static void main(String[] args){
    	solve();
    }
}

1.6子矩阵修改问题–蓝桥18440

二维差分模板题目
也是注意数值范围即可
package com.mj;
import java.util.Scanner;

public class Main{
	static int N = 1010;
	static int n,m,q;
	static int[][] a = new int[N][N];
	static int[][] b = new int[N][N];//差分数组
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		q = sc.nextInt();
		//输入数组
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				a[i][j] = sc.nextInt();
				//计算差分数组
				//前缀和s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
				b[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];
			}
		}
		
		//q组查询
		for(int i = 0; i < q; i++) {
			int x1 = sc.nextInt();
			int y1 = sc.nextInt();
			int x2 = sc.nextInt();
			int y2 = sc.nextInt();
			int d = sc.nextInt();
			b[x1][y1] += d;
			b[x2 + 1][y1] -= d;
			b[x1][y2+1] -= d;
			b[x2+1][y2+1] += d;
		}
		
		//输出二维数组
		for(int i = 1; i <= n; i++) {
			for(int j = 1; j <= m; j++) {
				//计算差分数组的前缀和
				a[i][j] = b[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
				System.out.print(a[i][j] + " ");
			}
			System.out.println();
		}
		
	}
    public static void main(String[] args){
    	solve();
    }
}

https://www.lanqiao.cn/problems/18439/learning/

https://www.lanqiao.cn/problems/18438/learning/

https://www.lanqiao.cn/problems/18440/learning/

https://www.lanqiao.cn/problems/19716/learning/

https://www.lanqiao.cn/problems/19703/learning/

https://www.lanqiao.cn/problems/3533/learning/

https://www.lanqiao.cn/problems/3514/learning

三、二分

知识点

二分:
1.序列二分:在序列中查找(不怎么考,会比较难?)
序列二分应用的序列必须是递增或递减,但可以非严格
只要r是mid-1,就对应mid=(l+r+1)/2
2.答案二分:最值
答案二分更重要的是思路,要自己可以二分的点,一般先写暴力,再将其转为二分。
3.浮点数二分:连续性

模板题目

1.1序列二分模板题–蓝桥18492

模板题目
package erfen;

import java.util.Scanner;

public class Test1 {
    static int N = 100010;
    static int n, q;
    static int[] a = new int[N];

    //找到等于x的最左边的数的下标
    static int getL(int l, int r, int x) {
        while (l < r) {
            int mid = l + r >> 1;//右移1表示除以2
            if (a[mid] >= x) r = mid;
            else l = mid + 1;
        }
        if (a[l] == x)
            return l;//返回下标
        else
            return -1;//不存在
    }

    //找到等于x的最右边的数的下标
    static int getR(int l, int r, int x) {
        while (l < r) {
            int mid = l + r + 1 >> 1;//右移1表示除以2
            if (a[mid] <= x) l = mid;
            else r = mid - 1;
        }
        if (a[l] == x)
            return l;//返回下标
        else
            return -1;//不存在
    }

    //找到大于等于x的第一个数的下标
    static int lower_bound(int l, int r, int x) {
        while (l < r) {
            int mid = l + r >> 1;//右移1表示除以2
            if (a[mid] >= x) r = mid;
            else l = mid + 1;
        }
        if (a[l] >= x)
            return l;//返回下标
        else
            return -1;//不存在
    }

    //找到大于x的第一个数的下标
    static int upper_bound(int l, int r, int x) {
        while (l < r) {
            int mid = l + r >> 1;//右移1表示除以2
            if (a[mid] > x) r = mid;
            else l = mid + 1;
        }
        if (a[l] > x)
            return l;//返回下标
        else
            return -1;//不存在
    }

    //主逻辑函数
    static void solve() {
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        q = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        for (int i = 0; i < q; i++) {
            int op = sc.nextInt();
            int l = sc.nextInt();
            int r = sc.nextInt();
            int x = sc.nextInt();
            if (op == 1) {
                System.out.println(getL(l, r, x));
            } else if (op == 2) {
                System.out.println(getR(l, r, x));
            } else if (op == 3) {
                System.out.println(lower_bound(l, r, x));
            } else if (op == 4) {
                System.out.println(upper_bound(l, r, x));
            }
        }
    }

    public static void main(String[] args) {
        solve();
    }
}

1.2最大通过数–蓝桥3346–前缀和+二分

本题利用了前缀和和二分
思想很重要,首先枚举左边,再在里面枚举右边的通过数。
先写暴力然后就很容易写二分。
注意数值范围

暴力

package erfen;

import java.util.Scanner;

public class Test2 {
    static int N = 200010;
    static int m,n;
    static long k;
    static long[] a = new long[N];
    static long[] b = new long[N];
    //主逻辑函数
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        m = sc.nextInt();
        k = sc.nextLong();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextLong();
            a[i] = a[i - 1] + a[i];//计算前缀和
        }
        for (int i = 1; i <= m; i++) {
            b[i] = sc.nextLong();
            b[i] = b[i - 1] + b[i];//计算前缀和
        }
        int ans = 0;
        for (int i = 0; i <= n; i++) {
            //循环左边
            if(a[i] > k) break;//a[0]为0,所以无需担心左边为0没有遍历右边
            long x = k - a[i];//左边可通过i关
            for (int j = 0; j <= m; j++) {
                if(x >= b[j]){//右边可通过j关
                    ans = Math.max(ans, i + j);
                }else{
                    break;
                }
            }
        }

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

二分

计算前缀和数组,它是递增的,可以应用二分
要二分就要找到单调的趋势,找到可以二分的点。
package erfen;

import java.util.Scanner;

public class Test2 {
    static int N = 200010;
    static int m,n;
    static long k;
    static long[] a = new long[N];
    static long[] b = new long[N];
    //主逻辑函数
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        m = sc.nextInt();
        k = sc.nextLong();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextLong();
            a[i] = a[i - 1] + a[i];//计算前缀和
        }
        for (int i = 1; i <= m; i++) {
            b[i] = sc.nextLong();
            b[i] = b[i - 1] + b[i];//计算前缀和
        }
        int ans = 0;
        for (int i = 0; i <= n; i++) {
            //枚举左边
            if(a[i] > k) break;//a[0]为0,所以无需担心左边为0没有遍历右边
            long x = k - a[i];//剩下的
            //二分第二个山洞,找到大于x的第一个数
            //因为是找大于x的第一个数,x可能是最后一个即m,所以r的取值要是m+1
            int l = 0, r = m + 1;
            while(l < r){
                int mid = l + r >> 1;
                if(b[mid] > x) r = mid;
                else l = mid + 1;
            }
            ans = Math.max(ans, i + l - 1);
        }


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

1.3答案二分模板–https://hydro.ac/d/shallowdream/p/33

求最小的最大值,这题和后面那道数列分段一样,都是要求一个最值。
这个最值是自己进行枚举来得到的,这是一个重要的思路。
第二个就是本题的k次加一操作转换为了元素要达到max需要消耗多少k值,由此找到最小的max

暴力

package erfen;

import java.util.Scanner;

public class Test3 {
    static int N = 100010;
    static int n;
    static long k;
    static int[] a = new int[N];
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        k = sc.nextLong();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        //枚举最小值
        for (int i = 1; i <= 1e14; i++) {
            long t = k;//每次都要重新初始化
            for (int j = 1; j <= n; j++) {
                //循环数组每个元素看能否达到i
                if(a[j] < i){
                    t = t -(i - a[j]);//a[j]需要(i - a[j])次加一操作才能达到i
                }
                //结束后进行判断
                if(t < 0){
                    //当前数组某个元素不能达到i,那整个数组都不能达到i
                    System.out.println(i - 1);
                    return;//结束全部
                }
            }
        }
    }
    public static void main(String[] args) {
        solve();
    }
}

二分

找到可以二分的点:随着枚举的最大的最小值越大,t的值即剩余的k操作越来越少。

image-20250314104140782

package erfen;

import java.util.Scanner;

public class Test3 {
    static int N = 100010;
    static int n;
    static long k;
    static int[] a = new int[N];
    //
    static boolean check(long m){
        long t = k;//每次都要重新初始化
        for (int j = 1; j <= n; j++) {
            //循环数组每个元素看能否达到m
            if(a[j] < m){
                t = t -(m - a[j]);//a[j]需要(m - a[j])次加一操作才能达到m
            }
            //结束后进行判断
            if(t < 0){
                //当前数组某个元素不能达到i,那整个数组都不能达到i
                /*System.out.println(i - 1);*/
                return false;//结束全部
            }
        }
        //整个循环结束,表示整个数组可以达到m
        return true;
    }
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        k = sc.nextLong();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        //二分最大的最小值
        long l = 1;
        long r = (long)1e14;
        while(l < r){
            long mid = l + r + 1 >> 1;
            if(check(mid)) l = mid;//true,表示可以达到mid,但是这个mid不一定是最大的。所以让l=mid。
            else r = mid - 1;
        }

        System.out.println(l);

    }
    public static void main(String[] args) {
        solve();
    }
}

1.4数列分段

本题的难点在于分段
思路:
1.枚举最小的最大值
2.分段的思想,采用cnt来记录段数,sum来记录当前段的和。

暴力

package erfen;

import java.util.Scanner;

public class Test4 {
    static int N = 100010;
    static int n,m;
    static int[] a  = new int[N];
    //判断能否做最小的最大值
    static boolean check(int x){
        int sum = 0;//记录当前段和
        int cnt = 1;//记录段数,最小也为1
        for (int i = 1; i <= n; i++) {
            if(sum + a[i] <= x){
                //当前段还可以继续加
                sum = sum + a[i];
            }else{
                sum = a[i];//另开一段
                cnt++;//段数加一
            }
        }
        return cnt <= m;//只有cnt大于m,才说明这个x不是最小的最大值
        //可以等于是因为元素可能较小,m给的大。
    }
    //主逻辑函数
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        //枚举最小的最大值
        for (int i = 1; i <= 1e9; i++) {
            if(check(i)) {
                System.out.println(i);
                return;//结束
            }

        }
    }
    public static void main(String[] args) {
        solve();
    }
}

二分

package erfen;

import java.util.Scanner;

public class Test4 {
    static int N = 100010;
    static int n,m;
    static int[] a  = new int[N];
    //判断能否做最小的最大值
    static boolean check(int x){
        int sum = 0;//记录当前段和
        int cnt = 1;//记录段数,最小也为1
        for (int i = 1; i <= n; i++) {
            if(a[i] > x) return false;
            if(sum + a[i] <= x){
                //当前段还可以继续加
                sum = sum + a[i];
            }else{
                sum = a[i];//另开一段
                cnt++;//段数加一
            }
        }
        return cnt <= m;//只有cnt大于m,才说明这个x不是最小的最大值
        //可以等于是因为元素可能较小,m给的大。
    }
    //主逻辑函数
    static void solve(){
        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
        }

        //二分最小的最大值
        //随着i的增大,cnt越来越小。
        int l = 1,r = (int)1e9;
        while(l < r){
            int mid = l + r >> 1;
            if(check(mid)) r = mid;
            else l = mid + 1;
        }
        System.out.println(l);
    }
    public static void main(String[] args) {
        solve();
    }
}

练习题

1.求阶乘–蓝桥2145

求末尾恰好有几个0。
思路:
只有2*5才可以得到10。
而且N!中,2的数量一定大于5的数量,所以要统计有多少个5,就可以知道有多少个0。
统计5就统计5的倍数,而对于一些特殊的数25,125,里面不止包含1个5。
对于N,只要一直除5,就可以得到5的数量了。这就是本题的第二个难点。

要注意可以二分的点,判断大于小于

要灵活变通,题目已经有了提示:这样的N不存在输出-1,就要注意判断

暴力

import java.util.Scanner;

public class main {
    static long k;
    //判断
    static boolean check(long x){
        long count = 0;//统计0的数量
        while(x != 0){
            count += x / 5;
            x = x / 5;
        }
        if(count == k) return true;
        else return false;
    }
    static void solve(){
        Scanner sc = new Scanner(System.in);
        k = sc.nextLong();

        //枚举n
        for (long i = 1; i <= (long)1e18; i++) {
            if(check(i)){
                System.out.println(i);
                return;//结束循环
            }
        }
        System.out.println(-1);//不存在输出-1
    }
    public static void main(String[] args) {
        solve();
    }
}

import java.util.Scanner;

public class main {
    static long k;
    //判断
    static long getCount(long x){
        long count = 0;//统计0的数量
        while(x != 0){
            count += x / 5;
            x = x / 5;
        }
        return count;
    }
    static void solve(){
        Scanner sc = new Scanner(System.in);
        k = sc.nextLong();

        //二分
        long l = 1, r = Long.MAX_VALUE - 1;//这里r不减1的话,l+r第一步就溢出了
        while (l < r){
            long mid = l + r >> 1;
            long count = getCount(mid);
            if(count >= k) r = mid;
            else l = mid + 1;
        }
        if(getCount(l) == k) System.out.println(l);
        else{
            System.out.println(-1);//不存在输出-1
        }
    }
    public static void main(String[] args) {
        solve();
    }
}

搜索

一、回溯法+二进制枚举 要求:省一会

1.递归实现排列型枚举

https://www.lanqiao.cn/problems/19684/learning/

package huisu;
//递归实现排列型枚举
//n 个正整数排成一行后随机打乱顺序,按字典序输出所有不同的方案。
//输入一行,包含一个正整数n
//输出n! 行,每一行为一种方案。字典序较小的先输出。

import java.util.Scanner;

//对于暴力做法,对于一个数就是一次循环,每次循环还要判断数字是否被上一层选中
//每一次的所有数选完并输出后,要让数字变回未被选中状态,进行下一次的选择
public class Test1 {
    //记录数字是否被选中
    static boolean[] st = new boolean[10];
    //用数组记录排列的数据
    static int[] path = new int[10];
    static int n;

    //回溯
    static void dfs(int u){//u表示的是这是第几个数的选择,本题我们把数的选择转移到数组中
        if(u > n){
            //所有的数字选完了,输出
            for (int i = 1; i <= n; i++) {
                System.out.print(path[i]);
            }
            //换行
            System.out.println();
        }
        //每一次的选择
        for (int i = 1; i <= n; i++) {
            //判断这个数是否被选过
            if(st[i]) continue;
            //没被选就选中它,并记下
            st[i] = true;
            path[u] = i;
            //选择下一个数
            dfs(u + 1);
            //回溯
            st[i] = false;
        }
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入n
        n = sc.nextInt();
        //输出
        dfs(1);

    }
    public static void main(String[] args) {
        solve();
    }
}
package com.mj;
import java.util.*;

public class Main{
	//记录数字是否被选中
	static boolean[] st = new boolean[10];
	//用数组记录排列的数据
	static int[] path = new int[10];
	static int n;
	
	//
	static void dfs(int u) {
		if(u > n) {
			//递归边界,输出
			for(int i = 1;i <= n; i++) {
				System.out.print(path[i] + " ");
			}
			System.out.println();//换行
		}
		//每一次的选择
		for(int i = 1;i <= n; i++) {
			//判断是否被选过
			if(st[i]) continue;
			st[i] = true;//没备选就选
			path[u] = i;//记下
			dfs(u + 1);//下一格数
			st[i] = false;//回溯
		}
	}
	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		
		n = sc.nextInt();
		//输出dfs
		dfs(1);
		
		
		
	}
    public static void main(String[] args){
    	solve();
    }
}

1.2带分数–蓝桥208

思路,1-9出现且只出现1次,进行9的全排列,把9个数的所有组合排列出来,再把加号和除号放进去,看看哪些符合条件
package com.mj;
import java.util.*;

public class Main{
	//记录数字是否被选中
	static boolean[] st = new boolean[15];
	//用数组记录排列的数据
	static int[] path = new int[15];
	static int n;
	static int ans;
	
	//
	static void check(String s) {
		for(int i = 1; i <= 7; i++) {//加号可以放置的位置
			for(int j = i + 1; j <= 8; j++) {//除以号可以放置的位置
				int A = Integer.parseInt(s.substring(0,i));
				int B = Integer.parseInt(s.substring(i,j));
				int C = Integer.parseInt(s.substring(j));
				
				if (C != 0 && A + (double)B / C == n) {
				    ans++;
				}
			}
		}
	}
	static void dfs(int u) {
		if(u > 9) {
			//递归边界,9个数全排列完毕
			StringBuilder sb = new StringBuilder();
			for (int i = 1; i <= 9; i++) {
			    sb.append(path[i]);
			}
			String s = sb.toString();
			check(s);
			
		}
		//每一次的选择
		for(int i = 1;i <= 9; i++) {
			//判断是否被选过
			if(st[i]) continue;
			st[i] = true;//没备选就选
			path[u] = i;//记下
			dfs(u + 1);//下一格数
			st[i] = false;//回溯
		}
	}
	
	//主逻辑函数
	static void solve() {
		Scanner sc = new Scanner(System.in);
		
		n = sc.nextInt();
		//
		dfs(1);
		
		System.out.print(ans);
		
		
	}
    public static void main(String[] args){
    	solve();
    }
}

2.递归实现指数型的枚举

https://www.lanqiao.cn/problems/19685/learning/


import java.util.Scanner;

public class Main {
    static int n;
    static int[] st = new int[20];//记录选与不选
    //递归函数
    static void dfs(int u){
        if(u > n){
            //数都选与不选完了
            //输出
            for (int i = 1; i <= n; i++) {
                if(st[i] == 1) System.out.print(i + " ");
            }
            //换行
            System.out.println();
            //返回
            return;
        }
        for (int i = 0; i <= 1; i++) {
            //0表示不选,1表示选
            st[u] = i;
            dfs(u + 1);//下一个数字
        }
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入n
        n = sc.nextInt();
        dfs(1);
    }
    public static void main(String[] args) {
        solve();
    }
}

package huisu;

import java.util.Scanner;

public class Test2 {
    static int n;
    static int[] st = new int[20];//记录选与不选
    //递归函数
    static void dfs(int u){
        if(u > n){
            //数都选与不选完了
            //输出
            for (int i = 1; i <= n; i++) {
                if(st[i] == 1) System.out.print(i + " ");
            }
            //换行
            System.out.println();
            //返回
            return;
        }
        /*for (int i = 0; i <= 1; i++) {
            //0表示不选,1表示选
            st[u] = i;
            dfs(u + 1);//下一个数字
        }*/
        st[u] = 0;
        dfs(u + 1);
        st[u] = 1;
        dfs(u + 1);
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入n
        n = sc.nextInt();
        dfs(1);
    }
    public static void main(String[] args) {
        solve();
    }
}

3.递归实现组合型枚举

https://www.lanqiao.cn/problems/19686/learning/

思路:每个数选与不选,只要等于3了,就输出结果;
//
额,我的思路根本写不出题解,也不是很对。
一定要注意审题和看样例了解题目啊
输出字典序,并且数字不重复!
所以就按照m个数字来,每次每个数字都循环(1->n),但由于不重复且递增,所以对于下一个数,是dfs(u + 1,i + 1)

import java.util.Scanner;

public class Main {
    static int n,m;
    static int[] st = new int[20];//记录选与不选
    //递归函数
    static void dfs(int u,int start){
        if(u > m){
            for (int i = 1; i <= m; i++) {
                System.out.print(st[i] + " ");
            }
            System.out.println();
            return;
        }
        for (int i = start; i <= n; i++) {
            st[u] = i;
            dfs(u + 1,i + 1);// 下一个数,保证是递增不重复的
        }
    }
    //主逻辑函数
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        //输入n,m
        n = sc.nextInt();
        m = sc.nextInt();
        dfs(1,1);//从第一个位置,1开始
    }
    public static void main(String[] args) {
        solve();
    }
}

4.蛋糕的美味值

https://www.lanqiao.cn/problems/8664/learning

思路:其实和第二题差不多,每次都是选和不选,到最后u>n时候,就循环计算sum,判断是否大于k,不是的话判断这些小于k的sum中最大的值。
package huisu;
import java.util.Scanner;
public class Test5 {
    static int n,k;
    //记录蛋糕
    static int[] taste = new int[25];
    //记录选择
    static int[] st = new int[25];
    static int Max = 0;
    //递归计算蛋糕的最大美味值
    public static void dfs(int u){
        if(u > n){
            int sum = 0;
            for (int i = 1; i <= n; i++) {
                if(st[i] == 1)
                    sum = sum + taste[i];
            }
            if(sum < k){
                Max = Math.max(Max,sum);
            }
            return;
        }
        for (int i = 0; i <= 1; i++) {
            st[u] = i;
            dfs(u + 1);
        }
    }
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        k = sc.nextInt();
        for (int i = 1; i <= n; i++) {
            taste[i] = sc.nextInt();
        }
        dfs(1);
        System.out.println(Max);

    }
    public static void main(String[] args) {
        solve();
    }
}

5.N皇后问题

https://www.lanqiao.cn/problems/1508/learning/

难点在于如何使得不在同一排,同一列,与棋盘边框成45度角的斜线。
把棋盘二维问题转换为一维数组的问题
对每列进行查找,找到位置后进行下一列的选择。就避免了二维问题。
这个与棋盘边框成45度角的斜线。就要找规律了。。。

要注意数值范围
package huisu;

import java.util.Scanner;

public class Test6 {
    static int n;
    static int ans;
    static boolean[] col = new boolean[30];
    static boolean[] zhu = new boolean[30];
    static boolean[] fu = new boolean[30];
    public static void dfs(int u){
        if(u > n){
            ans++;
            return;
        }
        //u表示第u行
        //循环的i表示第几列
        for (int i = 1; i <= n; i++) {
            //首先判断
            //不在同一排,同一列,与棋盘边框成45度角的斜线。
            if(col[i] || zhu[n - i + u] || fu[u + i]) continue;
            //选择
            col[i] = true;
            zhu[n - i + u] = true;
            fu[u + i] = true;
            dfs(u + 1);//下一行
            //回溯,释放位置
            col[i] = false;
            zhu[n - i + u] = false;
            fu[u + i] = false;
        }
    }
    public static void solve(){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        dfs(1);//从第一行开始
        System.out.println(ans);
    }
    public static void main(String[] args) {
        solve();
    }
}

6.五子棋对弈

https://www.lanqiao.cn/problems/19694/learning/

思路是对白棋进行递归判断
每次对每个格子都是选与不选,直至25个格子全部选完。
选完之后判断白棋的个数是不是13个
是的话再判断是否为平局。
平局就是排除掉横竖对角线,主副对角线的总和为0或5的。
package huisu;

public class Test7 {
    static int[] st = new int[30];
    static int[][] qi = new int[10][10];
    static int ans;
    //判断平局
    public static boolean check(){
        int k = 1;
        //1表示白棋,0表示黑棋
        //那么横竖和对角线的sum不能是0或者5
        //放到二维数组中更好计算判断
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                qi[i][j] = st[k];
                k++;
            }
        }
        //判断横竖
        int[] row = new int[6];
        int[] col = new int[6];
        for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                row[i] += qi[i][j];
                col[i] += qi[j][i];
            }
        }
        for (int i = 1; i <= 5; i++) {
            if(row[i] == 5 || row[i] == 0 || col[i] == 5 || col[i] == 0)
                return false;
        }

        //判断主副对角线
        int zhu = 0;
        int fu = 0;
        for (int i = 1; i <= 5; i++) {
            zhu += qi[i][i];
            fu += qi[i][6 - i];
        }
        if(zhu == 5 || zhu == 0 || fu == 5 || fu == 0)
            return false;

        //都判断完
        return true;
    }
    //递归函数
    public static void dfs(int u){
        if (u > 25){
            int count = 0;
            //判断白棋是否有13颗
            for (int i = 1; i <= 25; i++) {
                if(st[i] == 1)
                    count++;
            }
            if(count == 13){
                //有13颗,那黑棋12颗
                //接下来就判断是否平局
                if(check())
                    ans++;
            }
            //返回
            return;
        }
        //u表示每一格子
        for (int i = 0; i <= 1; i++) {
            st[u] = i;
            dfs(u + 1);//下一格
        }
    }
    public static void solve(){
        dfs(1);//对白棋进行选择
        System.out.println(ans);
    }
    public static void main(String[] args) {
        solve();
    }
}

在主副对角线的计算那里
        /*for (int i = 1; i <= 5; i++) {
            for (int j = 1; j <= 5; j++) {
                zhu += qi[i][i];
                fu += qi[i][5 - i + 1];
            }
        }*/
刚开始这么计算,是错误的,我重复计算了。呃呃呃。
二维数组还需要学。。。。

7.宝塔

https://www.lanqiao.cn/problems/20111/learning/


8.数字接龙

https://www.lanqiao.cn/problems/19712/learning/


java知识点

1.Java数组默认值
在Java中,当数组被定义但未被显式初始化时,数组元素会自动赋予默认值。不同数据类型的数组有不同的默认值。
整型数组默认值
对于整型数组(如byte、short、int、long),默认值为0。例如:
int[] intArray = new int[5];
System.out.println(intArray[0]); // 输出:0
无论是byte、short、int还是long,其默认值均为0
2.最大值:
Long.MAX_VALUE
在二分中可能会使用,计算mid时要注意溢出问题,l=1的话一般要减一操作。

蓝桥杯就这样子了,一边学一边玩了一个月,感觉明天就是寄了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ChCore Lab 01】Bomb Lab 拆炸弹实验(ARM汇编逆向工程)

文章目录 1. 前言2. 实验代码版本问题3. 关于使用问题4. 宏观分析5. read_line 函数介绍6. phase_0 函数6.1. read_int 函数6.2. 回到 phase_0 函数继续分析6.3. 验证结果 7. phase_1 函数7.2. 验证结果 8. phase_2 函数8.1. read_8_numbers 函数8.2. 回到 phase_2 函数继续分析…

二分答案----

二分答案 - 题目详情 - HydroOJ 问题描述 给定一个由n个数构成的序列a&#xff0c;你可以进行k次操作&#xff0c;每次操作可以选择一个数字&#xff0c;将其1&#xff0c;问k次操作以后&#xff0c;希望序列里面的最小值最大。问这个值是多少。 输入格式 第一行输入两个正…

Transformer多卡训练初始化分布式环境:(backend=‘nccl‘)

Transformer多卡训练初始化分布式环境:(backend=‘nccl’) dist.init_process_group(backend=nccl)在多卡环境下初始化分布式训练环境,并为每个进程分配对应的 GPU 设备。下面为你逐行解释代码的含义: 1. 初始化分布式进程组 try:dist.init_process_group(backend=nccl) e…

Kubernetes集群环境搭建与初始化

1.Kubernetes简介&#xff1a; Kubernetes是Google开源的一个容器编排引擎&#xff0c;它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时&#xff0c;通常要部署该应用的多个实例以便对应用请求进行负载均衡。 在Kubernetes中&#xff0c;我…

Jetson AGX Xavier开发套件使用方法

Jetson AGX Xavier是一款由NVIDIA推出的一款强大的嵌入式AI开发平台&#xff0c;适合边缘计算和目标检测任务。如果你手上有一台 Jetson AGX Xavier Developer Kit&#xff0c;就可以使用它进行明火烟雾目标检测实验。以此为例&#xff0c;为了使你能够从零开始设置设备并完成实…

数据可视化 —— 多边图应用(大全)

一、介绍&#xff1a; 多边形图&#xff0c;也就是在数据可视化中使用多边形来呈现数据的图表&#xff0c;在多个领域都有广泛的应用场景&#xff0c;以下为你详细介绍&#xff1a; 金融领域 投资组合分析&#xff1a;在投资组合管理中&#xff0c;多边形图可用于展示不同资…

小张的工厂进化史——工厂模式

小张的工厂进化史——工厂模式 一、简单工厂模式&#xff1a;全能生产线二、工厂方法模式&#xff1a;分品牌代工三、抽象工厂模式&#xff1a;生态产品族四、三种模式核心对比表五、结合Spring实现简单工厂&#xff08;实践&#xff09; 小张从华强北起家&#xff0c;最初只有…

C语言,原码、补码、反码

计算机是以补码来存储的 原码&#xff1a;正数最高位为&#xff1a;0&#xff1b;负数最高位为&#xff1a;1 &#xff08;最高位是符号位&#xff09; 正数&#xff1a;三码合一 如&#xff1a;2&#xff1a; 原码&#xff1a;0000 0000 0000 0000 0000 0000 0000 0010&#…

2025年智能合约玩法创新白皮书:九大核心模块与收益模型重构Web3经济范式

——从国库管理到动态激励的加密生态全栈解决方案 一、核心智能合约架构解析 1. 国库合约&#xff1a;生态财政中枢 作为协议的金库守卫者&#xff0c;国库合约通过多签冷钱包与跨链资产池实现资金沉淀。其创新点包括&#xff1a; 储备资产动态再平衡&#xff1a;采用预言机实…

【Android】Android 打包 Release 崩溃问题全解析:Lint 错误、混淆类丢失及解决方法大全

摘要&#xff1a; 在 Android 项目的 Release 打包过程中&#xff0c;经常遇到诸如 Lint 校验失败、程序闪退、类找不到等问题。本文将详细分析 Android 打包时常见的崩溃原因&#xff0c;特别是如何应对 Lint 报错、混淆引发的类丢失&#xff08;NoClassDefFoundError&#xf…

热门面试题第15天|最大二叉树 合并二叉树 验证二叉搜索树 二叉搜索树中的搜索

654.最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大…

【前缀和】矩阵区域和(medium)

矩阵区域和&#xff08;medium&#xff09; 题⽬描述&#xff1a;解法&#xff1a;代码Java 算法代码&#xff1a;C 算法代码&#xff1a; 题⽬描述&#xff1a; 题⽬链接&#xff1a;1314. 矩阵区域和 给你⼀个 m x n 的矩阵 mat 和⼀个整数 k &#xff0c;请你返回⼀个矩阵 …

一周学会Pandas2 Python数据处理与分析-Pandas2读取Excel

锋哥原创的Pandas2 Python数据处理与分析 视频教程&#xff1a; 2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili Excel格式文件是办公使用和处理最多的文件格式之一&#xff0c;相比CSV文件&#xff0c;Excel是有样式的。Pandas2提…

【MySQL】002.MySQL数据库基础

文章目录 数据库基础1.1 什么是数据库1.2 基本使用创建数据库创建数据表表中插入数据查询表中的数据 1.3 主流数据库1.4 服务器&#xff0c;数据库&#xff0c;表关系1.5 MySQL架构1.6 SQL分类1.7 存储引擎1.7.1 存储引擎1.7.2 查看存储引擎1.7.3 存储引擎对比 前言&#xff1a…

02-redis-源码下载

1、进入到官网 redis官网地址https://redis.io/ 2 进入到download页面 官网页面往最底下滑动&#xff0c;找到如下页面 点击【download】跳转如下页面&#xff0c;直接访问&#xff1a;【https://redis.io/downloads/#stack】到如下页面 ​ 3 找到对应版本的源码 https…

大模型上下文协议MCP详解(1)—技术架构与核心机制

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl1. MCP概述 1.1 定义与目标 MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的开放标准协议。它旨在解决AI大模型与外部工具、数据源及API之间的标准化交互问题…

Windows下安装depot_tools

一、引言 Chromium和Chromium OS使用名为depot_tools的脚本包来管理检出和审查代码。depot_tools工具集包括gclient、gcl、git-cl、repo等。它也是WebRTC开发者所需的工具集&#xff0c;用于构建和管理WebRTC项目。本文介绍Windows系统下安装depot_tools的方法。 二、下载depo…

解决 vite.config.ts 引入scss 预处理报错

版本号&#xff1a; "sass": "^1.86.3","sass-loader": "^16.0.5","vite": "^6.2.0" 报错1&#xff1a;[plugin:vite:css] [SASS] Error&#xff1a;Cant find stylesheet to import vite.config.ts 开始文件错…

MySQL学习笔记7【InnoDB】

Innodb 1. 架构 1.1 内存部分 buffer pool 缓冲池是主存中的第一个区域&#xff0c;里面可以缓存磁盘上经常操作的真实数据&#xff0c;在执行增删查改操作时&#xff0c;先操作缓冲池中的数据&#xff0c;然后以一定频率刷新到磁盘&#xff0c;这样操作明显提升了速度。 …

分布式锁和事务注解结合使用

在分布式系统中&#xff0c;事务注解&#xff08;如 Transactional&#xff09;与分布式锁的结合使用是保障数据一致性和高并发安全的核心手段。以下是两者的协同使用场景及技术实现要点&#xff1a; 一、事务注解的局限性及分布式锁的互补性 维度事务注解&#xff08;Transac…