蓝桥杯第 1 场算法双周赛 题解+Ac代码

提醒:篇幅可能有点长,为了方便,大家可以直接看目录快速查找想要的内容

1:三带一【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第1张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第2张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第3张图片

intput:

No
Yes
No
Yes
Yes

output:

No
Yes
No
Yes
Yes

思路:

1.要满足一个三带一的话,就是任意选三个数相等且和另一个数不相等一个数不等,有4种情况,这里注意不能4个数都相等,不然都是炸了(斗地主中的炸),那么可以直接写判断,也可以排个序,压缩码量

2.排序后,分两种情况,前三个数相等且和最后一个数不等,或者后三个数相等且和第一个数不等

AC_code:java


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

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

        String s;
        int T;  T= sc.nextInt();
        while(T-- >0){
            s=sc.next();

            char[] a=s.toCharArray();   //转化为字符数组

            Arrays.sort(a);

            if((a[0]==a[1]&&a[1]==a[2]&&a[2]!=a[3])||(a[3]==a[2]&&a[2]==a[1]&&a[1]!=a[0]))
                System.out.println("Yes");
            else System.out.println("No");
        }

    }
}

2:数树数【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第4张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第5张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第6张图片

intput:

3 6
R
L
LL
LR
RL
RR

output:

2
1
1
2
3
4

思路:递推/找规律

把二叉树放到一行当中,如下

1

1 2

1 2 3 4

1 2 3 4 5 6 7 8

1.当只有一层时,ans=1,当大于一层时,找找规律(ans为答案)

2.观察左右子树,每向下一层时,遇到L,ans=ans*2-1,遇到R,ans=ans*2

Ac_code:java


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

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),q=sc.nextInt();

        String s;
        while(q-->0){
            s=sc.next();
            int ans=1;
            for (int i = 0; i < s.length(); i++) {
                if(s.charAt(i)=='L')    ans=ans*2-1;
                else ans=ans*2;
            }
            System.out.println(ans);
        }


    }
}

3:分组【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第7张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第8张图片

input:

5 3
8 4 3 6 9

output:

1

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第9张图片

思路:二分+贪心

1.怎么样才能让极差最小呢?贪心的想应该让身高相差小的分在一组,身高相差小那么有序的话就更好进一步思考,故先排一个序,排序后求极差值直接用最大值-最小值即可。

2.分成k组,那么要求出k个极差,让这k个极差的最大值最小,极差满足二段性,故用二分可以求

Ac_code:java

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

public class Main {

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

        int []a=new int[n];
        for(int i=0;i>1;
            if(check(a,mid)) r=mid;
            else l=mid+1;
        }
        System.out.println(r-1);
    }

    //检查极差为mid是否满足条件
    private static boolean check(int[] a, int mid) {
        int cnt=1;  //记录分成几队
        for(int l=0,r=0;r=mid){ //注意这里>最后输出r,>=最后输出r-1
                l=r;    cnt++;
                if(cnt>k)   return false;
                    //分的队大于k,返回false,扩大极差l=mid+1
            }
        }
        return true;    //cnt小于等于k组  r=mid
    }
}

4:健身【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第10张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第11张图片

input:

10 3 3
1 4 9
0 3
1 7
2 20

output:

30

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第12张图片

思路:完全背包

1.把空闲的时间区间段拆出来,看成一个小的背包容量

2.对拆出来的每个小背包,跑一个完全背包,累加每一个小背包的最大价值就是答案了

Ac_cod:java

import java.util.Scanner;

public class Main {
    static int n,m,q;
    static int N=(int)2e5+7;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);

        n=sc.nextInt();
        m=sc.nextInt();
        q=sc.nextInt();

        int[] days=new int[q+2];    //纪录那些天不能去锻炼
        for (int i = 1; i <=q; i++) {
            days[i]=sc.nextInt();
        }

        int v[]=new int[m+1];
        int w[]=new int[m+1];

        for (int i = 1; i <=m; i++) {
            int t=sc.nextInt();
            v[i]=1<

5:契合匹配【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第13张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第14张图片蓝桥杯第 1 场算法双周赛 题解+Ac代码_第15张图片

input:

5
AbbCd
BcDaB

output:

Yes
2

蓝桥杯第 1 场算法双周赛 题解+Ac代码_第16张图片

思路:字符串哈希

1.两个齿轮都可以旋转,可以只看成一个齿轮可以旋转,让我们直接看s串,因为s是可以旋转的故可以直接拼接复制一倍s串(s+s),方便后续操作,

2.预处理出来与t匹配的串(大小写字母反转),记为target串,在s串中找到target串,找到了输出Yes,否则输出No

3.在s中找target串时,枚举起点记为i,如果匹配成功,注意是可以左右旋转的,可以把前1~i-1个字符移动后面,或者把i+1~n个字符移到前面,对两者取min(i-1,n-i)

4.匹配成功输出Yes并输出最小的旋转次数,否输出No

Ac_code:java

import java.util.Scanner;

public class Main {

    static int base=131;
    static int mod=(int)1e9+7;
    static int N=(int)2e6+7;

    static long[] hash1=new long[N];
    static long[] hash2=new long[N];
    static long[] p=new long[N];


    public static long get1(int l,int r){   //获得s串的hash值
        return ((hash1[r]-hash1[l-1]*p[r-l+1])%mod+mod)%mod;
    }

    public static long get2(int l,int r){   //获得与t匹配的hash值
        return ((hash2[r]-hash2[l-1]*p[r-l+1])%mod+mod)%mod;
    }

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

        String s=sc.next();
        String t=sc.next();

        //保证下标从1开始
        s=' '+s+s;  //可以旋转,复制一倍
        t=' '+t;
        char cht[]=t.toCharArray(); //t串转化为字符数组
        
        for(int i=1;i<=n;i++){ //将t串大写变小写,小写变大写
            if(cht[i]>='A'&&cht[i]<='Z') cht[i]+=32;
            else cht[i]-=32;
        }

        p[0]=1;
        for(int i=1;i<=n+n;i++){ //预处理hash值
            hash1[i]=(hash1[i-1]*base+s.charAt(i))%mod;
            if(i<=n) {
                hash2[i]=(hash2[i-1]*base+cht[i])%mod;
                p[i]=p[i-1]*base%mod;
            }
        }

        long target=get2(1,n); //获得与t匹配的串
        int ans=n;
        for(int i=1;i<=n;i++){
            if(target==get1(i,i+n-1))   //匹配成功,更新答案
                ans=Math.min(ans,Math.min(i-1,n-i+1));
        }       //将1~i-1个字符后移,或者i~n个字符前移,两者取min

        if(ans==n) System.out.println("No");
        else{
            System.out.println("Yes");
            System.out.println(ans);
        }
    }
}

6:奇怪的线段【算法赛】 - 蓝桥云课 (lanqiao.cn)

题面:蓝桥杯第 1 场算法双周赛 题解+Ac代码_第17张图片

input:

4 3
1 3
2 5
3 7 
4 8
1 5
2 9
5 1

output:

1
2
3

思路:树状数组/线段树

简述题意:给你n个线段,m个询问,问包含a且不包含b的线段的数量有多少

对每个询问直接遍历一遍所有的线段是会tle的(时间复杂度n*q),考虑如何优化呢?这里对a,b分情况讨论

1.对a,b端点的大小分情况讨论,a==b时 答案为0

2.a

3.a>b时,从大到小遍历数轴上的点(此时a为右端点,b为左端点),遇到右端点就将右端点对应的所有左端点处+1,并计算此时左端点在[b+1,a]的个数,即为右端点为a,左端点为b的答案

4.这题用到了,区间查询,单点修改,故直接上树状数组,当然线段树也行,还有注意java要快读,cpp用scanf就行

Ac_code:java

import java.io.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Scanner;

import static java.awt.AWTEventMulticaster.add;

public class Main {
    static int N=(int)2e5+7;
    static int tr[]=new int[N];

    public static void add(int idx,int val){
        for(int i=idx;i0;i-=i&-i)    res+=tr[i];
        return res;
    }

    //java这题用Scanner会超时,故写了一个快读
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);

        int n=nextInt(),m=nextInt();

        //l[R]:右端点为R对应的的所有左端点
        //r[L]:左端点为L对应的所有的右端点
        //q[a]:端点a里存的是端点b,与第id个询问
        ArrayList[] l=new ArrayList[N];
        ArrayList[] r=new ArrayList[N];
        ArrayList[] q=new ArrayList[N];

        for(int i=0;i();
            r[i]=new ArrayList();
            q[i]=new ArrayList<>();
        }

        for(int i=1;i<=n;i++){
            int L=nextInt(),R=nextInt();
            l[R].add(L);
            r[L].add(R);
        }

        for(int i=0;ia)   //左端点为a,右端点为b
                    ans[p.id]=sum(p.b-1)-sum(a-1);
        }

        //记得清0
        for(int i=0;ib
        //枚举右端点a,记录左端点在[b+1,a]中的数量
        for(int a=N-1;a>=1;a--){
            for(int L:l[a]) add(L,1);
            for(Node p:q[a])
                if(p.b

双周赛题解将持续更新,希望对你有用!

描述有误,欢迎指正,

你可能感兴趣的:(蓝桥杯&数据结构与算法,蓝桥杯,职场和发展)