蓝桥杯省一你一定不能错过的模板大全(第二期)

第二期

基础算法(二) ✨

同步收录👇

蓝桥杯上岸

大家好 我是寸铁 ✨

冲刺蓝桥杯省一模板大全来啦 💥 ~

蓝桥杯4月8号就要开始了 🙏 ~

还没背熟模板的伙伴们背起来 💪 💪 💪

祝大家4月8号蓝桥杯上岸 ☀️ ~

往期回顾

蓝桥杯上岸必背!!!(第一期)

蓝桥杯必背! ! ! (第二期)

考点秘籍

蓝桥杯省一你一定不能错过的模板大全(第一期)

蓝桥杯每日一题 最少刷题数

蓝桥杯每日一题 求阶乘

蓝桥杯 Java 省赛 B 组(初赛)填空题

Java快读快写

双指针算法

双指针是一种算法思想,没有固定的模板 ✊

所以,我们结合例题去理解记忆这种思想效果 🌟 比较好!

双指针算法 👉蓝桥杯必背第二期

前缀和

顺序:
先求一遍所有的前缀和
再作差求自己想要的区间前缀和

模板题

核心

s[i]=s[i-1]+a[i]
s[r]-s[l-1]

写法1

import java.util.*;
public class Main{
    static int N=100010;
    static int a[]=new int[N];
    static int s[]=new int[N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n =sc.nextInt();
        int m=sc.nextInt();
        for(int i=1;i<=n;i++)a[i]=sc.nextInt();
        for(int i=1;i<=n;i++){
            s[i]=s[i-1]+a[i];
        }
        while(m-->0){
            int l=sc.nextInt();
            int r=sc.nextInt();
            System.out.println(s[r]-s[l-1]);
        }
    }
}

写法2

import java.util.*;
public class Main{
    static int N=100010;
    static int s[]=new int[N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n =sc.nextInt();
        int m=sc.nextInt();
        for(int i=1;i<=n;i++)s[i]=sc.nextInt();
        for(int i=1;i<=n;i++)s[i]+=s[i-1];
        while(m-->0){
            int l=sc.nextInt();
            int r=sc.nextInt();
            System.out.println(s[r]-s[l-1]);
        }
    }
}

二维前缀和

顺序:
先求一遍所有的前缀和
再作差求自己想要的区间前缀和

实际上是将一维看作二维处理

通常用于求矩阵内所有数的和,像炸弹、爆炸范围等等

模板题

import java.util.*;
public class Main{
    static int N=1010;
    static int a[][]=new int[N][N];
    static int s[][]=new int[N][N];    
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int q=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=sc.nextInt();
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
            }
        }
        while(q-->0){
            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]);
        }
        
    }
}

背完模板后,下面让我们小试牛刀 👊

激光炸弹

Accode

import java.util.*;
public class Main{
    static int N=100010;
    static int a[]=new int[N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int k=sc.nextInt();
        for(int i=1;i<=n;i++)a[i]=sc.nextInt();
        int res=0;
        for(int R=1;R<=n;R++){
            for(int L=1;L<=R;L++){
                int sum=0;
               for(int i=L;i<=R;i++){
                 sum+=a[i];  
               }
               if(sum%k==0)res++;
            }
        }
        System.out.println(res);
    }
}

K倍区间:

Accode

//同余定理
import java.util.*;
public class Main{
    static int N=100010;
    static long s[]=new long[N];
    static long cnt[]=new long[N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        long n=sc.nextLong();
        long k=sc.nextLong();
        for(int i=1;i<=n;i++)s[i]=sc.nextInt();
        for(int i=1;i<=n;i++){
        s[i]+=s[i-1];
        }
        long res=0;
        cnt[0]=1;
        for(int i=1;i<=n;i++){
            res+=cnt[(int)(s[i]%k)];
            cnt[(int)(s[i]%k)]++;
        }
        System.out.println(res);        
    }
}

四平方和

Accode

import java.util.*;
public class Main{
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        Map<Integer,int []>map=new HashMap<>();
        int n=sc.nextInt();
        for(int c=0;c*c<=n;c++){
            for(int d=0;d*d+c*c<=n;d++){
                int sum=c*c+d*d;
                if(!map.containsKey(sum))map.put(sum,new int[]{c,d});
            }
        }
        for(int a=0;a*a<=n;a++){
            for(int b=0;a*a+b*b<=n;b++){
                int sum=a*a+b*b;
                if(map.containsKey(n-sum)){
            System.out.println(a+" "+b+" "+map.get(n-sum)[0]+" "+map.get(n-sum)[1]);
                return ;
                }
            }
        }
    }
}

差分

差分由于直接插入输入的元素比较难插
所以一般是通过差分插入元素insert(i,j,i,j,a[i][j])

核心

a[]:前缀和数组
b[]:差分数组
b[l]+=c;
b[r+1]-=c;
顺序先差分再求一遍前缀和

模板题

import java.util.*;
public class Main{
    static int N=100010;
    static int a[]=new int[N];
    static int b[]=new int[N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        for(int i=1;i<=n;i++)a[i]=sc.nextInt();
        for(int i=1;i<=n;i++){
            insert(i,i,a[i]);
        }
        while(m-->0){
            int l=sc.nextInt();
            int r=sc.nextInt();
            int c=sc.nextInt();
            insert(l,r,c);
        }
        for(int i=1;i<=n;i++){
            a[i]=a[i-1]+b[i];
        }
        for(int i=1;i<=n;i++)System.out.print(a[i]+" ");
    }
    public static void insert(int l,int r,int c ){
        b[l]+=c;
        b[r+1]-=c;
    }
}

二维差分

关键点:

二维差分和以往的处理顺序不同!

像前缀和是从右下到左上
而差分是从左上到右下去处理差分
(x1,y1)-->(x2,y2)这块区域内加上C
顺序先差分再求一遍前缀和

模板题

import java.util.*;
public class Main{
    static int N=1010;
    static int a[][]=new int [N][N];
    static int b[][]=new int [N][N];
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int q=sc.nextInt();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=sc.nextInt();
                insert(i,j,i,j,a[i][j]);
            }
        }
        while(q-->0){
            int x1=sc.nextInt();
            int y1=sc.nextInt();
            int x2=sc.nextInt();
            int y2=sc.nextInt();
            int c=sc.nextInt();
            insert(x1,y1,x2,y2,c);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+b[i][j];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
        
        
    }
    public static void insert(int x1,int y1,int x2,int y2,int c){
        b[x1][y1]+=c;
        b[x2+1][y1]-=c;
        b[x1][y2+1]-=c;
        b[x2+1][y2+1]+=c;
    }
}

位运算(lowbit)

一般不会单独考,lowbit常用于拔高题的进制处理的优化

模板题

可以直接记下来

import java.util.*;
public class Main{
    
    public static void main(String []args){
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        while(n-->0){
            int sum=0;
            int x=sc.nextInt();
            while(x!=0){
            x-=lowbit(x);
            sum++;
            }
            System.out.print(sum+" ");
        }
    }
    public static int lowbit(int x){
        return x&-x;
    }
}

离散化

很少看到,时间紧的同学可以跳过,重点还是前几个!

模板题

import java.io.*;
import java.util.*;

public class Main{
    public static void main(String[] args) throws IOException {
        int N = 300010;
        int[] a = new int[N];
        int[] s = new int[N];
        List<Integer> allS = new ArrayList<>();
        List<PIIs> add = new ArrayList<>();
        List<PIIs> query = new ArrayList<>();

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] str = reader.readLine().split(" ");
        int n = Integer.parseInt(str[0]); // n次操作
        int m = Integer.parseInt(str[1]); // m次询问
        for (int i = 0; i < n; i++) {
            String[] str1 = reader.readLine().split(" ");
            int x = Integer.parseInt(str1[0]);
            int c = Integer.parseInt(str1[1]);
            add.add(new PIIs(x, c));
            allS.add(x);
        }
        for (int i = 0; i < m; i++) {
            String[] str2 = reader.readLine().split(" ");
            int l = Integer.parseInt(str2[0]);
            int r = Integer.parseInt(str2[1]);
            query.add(new PIIs(l, r));
            allS.add(l);
            allS.add(r);
        }
        reader.close();
        Collections.sort(allS);
        int unique = unique(allS);
        allS = allS.subList(0, unique);
        for (PIIs item : add) {
            int x = find(item.getFirst(), allS);
            a[x] += item.getSecond();
        }
        for (int i = 1; i <= allS.size(); i++) {
            s[i] = s[i - 1] + a[i];
        }
        for (PIIs item : query) {
            int l = find(item.getFirst(), allS);
            int r = find(item.getSecond(), allS);
            System.out.println(s[r] - s[l - 1]);
        }
    }

    public static int unique(List<Integer> list) {
        int j = 0;
        for (int i = 0; i < list.size(); i++) {
            if (i == 0 || list.get(i) != list.get(i - 1)) {
                list.set(j++, list.get(i));
            }
        }
        return j;
    }

    public static int find(int x, List<Integer> allS) {
        int l = 0;
        int r = allS.size() - 1;
        while (l < r) {
            int mid = l + r >> 1;
            if (allS.get(mid) >= x) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return r + 1;
    }
}

class PIIs implements Comparable<PIIs>{
    private int first;
    private int second;

    public int getFirst() {
        return first;
    }

    public int getSecond() {
        return second;
    }

    public PIIs(int first, int second) {
        this.first = first;
        this.second = second;
    }
    public int compareTo(PIIs o) {
        return Integer.compare(first, o.first);
    }
}

区间合并

(1)按区间的左端点排序

st:左端点ed:右端点
下一扫描区间st上一扫描区间位置关系。

(2)扫描整个区间,在这一过程中,把有交集的区间进行合并。

(3)在前面左端点排好序的前提下,分为3种情况:

1.当前扫描区间上一扫描区间内,无需统计
2.当前扫描区间的st落在上一扫描区间(含ed),进行统计
3.当前扫描区间的st大于上一扫描区间的ed
整个是独立区间,进行统计。

模板题

题解

import java.util.*;
public class Main{
	public static void main(String []args) {
	Scanner in = new Scanner(System.in);
	int n = in.nextInt();
	List<PII>alls = new ArrayList<>();
	for(int i=0;i<n;i++) {
		int l =in.nextInt();
		int r =in.nextInt();
		alls.add(new PII(l,r));
	}
	Collections.sort(alls);
	int res = qu(alls);
	System.out.println(res);			
}
	public static int qu(List<PII> list) {
		List<PII> res = new ArrayList<>();
		int st =(int) -2e9;
		int ed =(int) -2e9;
		for(PII item:list) {
			if(ed<item.x) {
				if(ed!=-2e9)res.add(new PII(st,ed));
				st=item.x;
				ed=item.y;
			}
			else ed=Math.max(ed, item.y);
		}
			if(st!=-2e9)res.add(new PII(st,ed));
		return res.size();
		}
	}
class PII implements Comparable<PII>{
	int x,y;
	public PII(int x,int y) {
		this.x=x;
		this.y=y;
	}
	public int compareTo(PII o) {
		return Integer.compare(x, o.x);
	}
	
}

看到这里,不妨点个关注 💖

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
第十一届蓝桥杯赛第二场java大学b组真题共分为两道编程题和一道综合应用题,以下是真题及解析。 第一题是给定一个字符串,求出字符串中所有数字的总和。首先我们可以使用正则表达式来匹配字符串中的数字,然后将匹配到的数字累加起来即可。可以使用Java中的Pattern和Matcher类来实现正则匹配,具体代码如下: ```java import java.util.regex.*; public class Main { public static void main(String[] args) { String str = "abc123def456ghi789"; int sum = 0; Pattern pattern = Pattern.compile("\\d+"); Matcher matcher = pattern.matcher(str); while(matcher.find()) { sum += Integer.parseInt(matcher.group()); } System.out.println("数字总和为:" + sum); } } ``` 第二题是给定两个字符串,判断第二个字符串是否是第一个字符串的子串。可以使用Java中的contains()方法来判断一个字符串是否包含另一个字符串。具体代码如下: ```java public class Main { public static void main(String[] args) { String str1 = "abcdefg"; String str2 = "cde"; if (str1.contains(str2)) { System.out.println("第二个字符串是第一个字符串的子串!"); } else { System.out.println("第二个字符串不是第一个字符串的子串!"); } } } ``` 综合应用题是实现一个简单的计算器,根据输入的两个数字和运算符进行相应的运算并输出结果。我们可以使用Java中的Scanner类来获取用户输入的数字和运算符,并根据运算符进行相应的运算。具体代码如下: ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入第一个数字:"); int num1 = scanner.nextInt(); System.out.print("请输入第二个数字:"); int num2 = scanner.nextInt(); System.out.print("请输入运算符(+、-、*、/):"); String operator = scanner.next(); double result = 0; switch(operator) { case "+": result = num1 + num2; break; case "-": result = num1 - num2; break; case "*": result = num1 * num2; break; case "/": result = num1 / num2; break; default: System.out.println("无效的运算符!"); } System.out.println("计算结果为:" + result); } } ``` 以上就是第十一届蓝桥杯赛第二场java大学b组真题及解析的回答,希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寸 铁

感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值