第27场蓝桥杯入门赛AK代码及详细讲解(java)

发布于:2025-03-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

第一题.  38红包

问题简述:

从1到2025,有多少个数是3或者8或者38的倍数。

问题解答:不多说了,直接上代码

代码:

public class Main{
    public static void main(String[] args) {
        int count = 0;
        for (int i = 1; i <= 2025; i++) {
            if (i % 3 == 0 || i % 8 == 0 || i % 38 == 0) {
                count++;
            }
        }
        System.out.println(count);
    }
}

第二题:祝福语

问题简述:

现有一个S字符串,求出T字符串,T满足条件:

1.不是S字符串的子串  2.字典序最小

问题解答:

思考:

我们先思考,字典序要最小,那么T一定都是a。

例如aab

我们可以想到最小的字典序子串

a   - >  aa - >  aaa 

那么前两个没有满足条件,我们输出aaa;所以我们得出结论:

要保证T不是S的子串,我们的  T 中 a 的数量  一定是( S 中 连续a 的数量 + 1)

代码:

import java.util.Scanner;

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

        int cnt = 0, tmp = 0;

        for (char ch : s.toCharArray()) {
            if (ch == 'a') {
                tmp++;
            } else {
                cnt = Math.max(cnt, tmp);
                tmp = 0;
            }
        }
        cnt = Math.max(cnt, tmp);

        System.out.println("a".repeat(cnt + 1));
    }
}

第三题:社区服务

问题简述:

给你 n 个数字(只能是01)代表二进制数字,求出0 旁边 距离最近的1 的 距离。

问题解答:

思考:

1010100

我们可以看到,有些0,左边也有1,右边也有1,那距离最近的肯定是二者最小。

即Math.min(left,right);

1.那我们可以先考虑 各个 0距离左边  最近的  1 的距离。然后用一个数组ds记录.

我们用一个last  记录左边(前面)最新的 1 的值。(从左到右扫)

2.然后我们考虑 各个 0距离右边  最近的  1 的距离。然后更新数组ds的记录.

我们用一个last  记录右边(前面)最新的 1 的值。(从右到左扫)

然后就是ds里  不是0  的 就是结果。

代码:

import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt(); 
        String S = scanner.next();  
        scanner.close();
        int[] ds = new int[n];  
        int last = -1; 
        for (int i = 0; i < n; i++) {
            if (S.charAt(i) == '1') {
                last = i;
            } else {
                ds[i] = (last == -1) ? Integer.MAX_VALUE : (i - last);
            }
        }
        last = -1;
        for (int i = n - 1; i >= 0; i--) {
            if (S.charAt(i) == '1') {
                last = i;  
            } else {
                int rightDist = (last == -1) ? Integer.MAX_VALUE : (last - i);
                ds[i] = Math.min(ds[i], rightDist); 
            }
        }
        for (int i = 0; i < n; i++) {
            if (S.charAt(i) == '0') {
                System.out.print((ds[i] == Integer.MAX_VALUE ? -1 : ds[i]) + " ");
            }
        }
    }
}

第四题:表演队

问题简述:

我们需要从N个数中,选出K个数,使得最小差异值 之和(计算公式在题目里)最小。

问题解答:

思考:

由于这种题目结果并没有和顺序有关系,所以我们先排序。

排序之后,我们发现,相邻两个的差异值最小。 -----1.

那怎么选取K个,能使得他们的差异值之和最小。

其实结论:排序后选择连续的 K 个数可以使得总的绝对差之和最小

这里我就不推导了,大家可以举个例子思考一下。

那我们知道这个结论了,那我们就可以求出这题了。这题就变成了求出连续K个数的绝对差和的最小

连续k个数我们可以想到滑动窗口,那我们在求k个数的绝对差的和

即S1,S2,S3,S4,S5,S6,S7....SK

S = (S1 - S2) + (S1 - S3) + (S1 - S4) +....+ (S1 - SK) + (S2 - S3) +.. +  (S2 - SK) + ...

    = (S2 + S3 + S4 + ...+ SK ) - (K - 1) * S1    +

         (S3 + S4 + ...SK) - (K - 2) * S2  + .....+

所以我们可以想到前缀和来预处理降低时间复杂度。

然后我们滑动窗口求出最小的差异值接得到结果了。

代码:

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt(),k=scan.nextInt();
        int[] a = new int[n];
        for(int i = 0; i<n; i++) {
            a[i] = scan.nextInt();
        }
        Arrays.sort(a);
        long[] pre = new long[n+1];
        for(int i = 1; i<pre.length; i++) {
            pre[i] = pre[i - 1] + a[i - 1];
        }
        long ans = 0;
        for(int i = 1; i<k+1; i++) {
            ans += (pre[k] - pre[i])  -(long)(k - i) * a[i - 1];
        }
        long res = ans;
        for(int i = 1; i< n- k + 1; i++) {
          ans -= (pre[k + i - 1] - pre[i - 1] - (long)k * a[i - 1]);
            ans += (long)(k - 1) * a[i + k - 1];
            ans -= (pre[k + i - 1] - pre[i]);
            res = Math.min(res, ans);
        }
        System.out.println(res);
        scan.close();
    }
}

 第五题:花束搭配

问题简述:

给你n列数,每列有2个数,让你 选取两列数 满足条件的方案数:

注意:i列 和 j 列提供两种方案。

条件:两列数为a b

                         c  d     满足 a + b > c + d

问题解答:

思考:

我们看一下这个条件: a + b > c + d;  移一下项

                                     a - c >  - (b - d);移一下项

                                     (a - c) + (b -d) > 0;

那也就是,我们只需要枚举每一列的差值c,然后找到满足这个条件的就计数count++;

那样的话就是O(n2)的,c1 + c2 > 0  就行

那我们可以给他们的差值C,排序,使用左右双指针

因为这样的话枚举最大值 j ,我们找到最小的值 i 满足条件,那么中间的都满足条件count +=  j - i;

枚举最小值 i ,我们找到最大的值 j 满足条件,那么中间的都满足条件count +=  j - i;

最终的结果为count * 2

代码:

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

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] A = new int[n];
        int[] B = new int[n];
        for (int i = 0; i < n; i++) {
            A[i] = in.nextInt();
        }
        for (int i = 0; i < n; i++) {
            B[i] = in.nextInt();
        }
        in.close();
        long[] delta = new long[n];
        for (int i = 0; i < n; i++) {
            delta[i] = A[i] - B[i];
        }
        Arrays.sort(delta);
        long count = 0;
        int i = 0, j = n - 1;
        while (i < j) {
            if (delta[i] + delta[j] > 0) {
                count += (j - i);
                j--;  
            } else {
                i++;  
            }
        }
        long ans = count * 2;
        System.out.println(ans);
    }
}

第六题:妇女唇膏

问题简述:

给你N个数,求出最小正整数b,使得n个数都满足:

a +  b = a ^ b

问题解答:

思考:

直接记结论就好了:异或运算相当于无进位加法运算

a + b = a ^ b等价于 a & b = 0;

举个例子:a = 2(10),b = 1(0,1)

则a ^ b = a + b = 3,此时 a & b = 0;

                  a = 3(11),b = 1(01)

则a ^ b = 2  a +b = 4;  此时 a & b = 0;

我们可以让所以数按位或,求出他们所有在二进制数上的1的位置,然后取反

我们求出最低位的1,即为最小的正整数b,即为结果。

代码: 

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans |= scanner.nextInt();
        }
        System.out.println(~ans & -~ans);
        scanner.close();
    }
}

上面内容制作不易,喜欢的点个赞和收藏支持一下吧!!

后期会持续更新更多算法内容,如果想跟随共同学习,就点点关注把(