蓝桥杯 新生编程排位赛5 解题报告

前言


整体评价

这相当于蓝桥云课 正式推出算法赛前的公测,主要面向的是大一新生。

比赛题还是以语法题为主,被戏称为"幼稚园杯",^_^。

这场的E题开始加了难度,而且评测的数据有些弱,让一些不正确的算法也过了。看着哪些错误的代码及其思路,突然满眼都是自己大一时的场景。

链接:新生编程排位赛5


A. 妮妮的歌词改编

Q: 就是把一个字符串,元音字母转大写,非元音字母转小写

元音字母为 a, e, i, o, u

思路: 可以先把字符串整体变为小写,然后对元音字母特殊处理,这样处理的逻辑分支最少。

import java.util.Scanner;
import java.io.BufferedInputStream;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
        int t = sc.nextInt();
        while (t-- > 0) {
          // 统一转化为小写
          String s = sc.next().toLowerCase();
          char[] str = s.toCharArray();
          for (int i = 0; i < str.length; i++) {
            // 对元音字母特殊处理
            if ("aeiou".indexOf(str[i]) != -1) {
                str[i] = (char)(str[i] - 'a' + 'A');
            }
          }
          System.out.println(new String(str));
        }
    }

}

B. 小桥的小红书判断法

Q: 如果关注数x是粉丝数y的10倍以上(严格), 那它就是异常账号

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int x = sc.nextInt(), y = sc.nextInt();
            if (x > 10 * y) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
    }
}

C. 小桥的零花钱调整

Q:  2000元纸币可以换4张500元的纸币,求n张2000元可以换多少张500元纸币?

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(4 * n);
    }
}

D. 蓝桥村的神秘农田

Q: x \in [a, b], y \in [c, d], 求 x \times y的最大值, 注意a,b,c,d可能是负数

因此这个解,需要两端点彼此叉乘,求最大

max(a*c, a *d, b*c, b*d)

import java.util.Scanner;

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

        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();
        int d = sc.nextInt();

        int res = Math.max(Math.max(a * c, a * d), Math.max(b * c, b * d));

        System.out.println(res);
    }
}


E. 阿坤老师的课堂挑战

Q: 就是一个数组,支持区间[l, r]加x,  求可以放弃某次操作,使得最大的数最小。

这是一道RMQ的题,习惯了语法题,这题有些不敢相信自己的眼睛和直觉。

当然这题也可以使用二分,毕竟最大最小,已经可以刻在基因里了。

思路:差分预处理,然后构建ST表, 然后枚举每一次操作(撤销)

min_{i=0}^{i=m} max(ST[0, l - 1], ST[l, r] - x_i, ST[r + 1, n])

import java.io.BufferedInputStream;
import java.util.Scanner;
import java.util.function.BiFunction;

public class Main {

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

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


        long[] diff = new long[n + 2];
        long[] arr = new long[n + 1];

        int[][] items = new int[q][3];
        for (int i = 0; i < q; i++) {
            int l = sc.nextInt(), r = sc.nextInt(), x = sc.nextInt();
            diff[l] += x;
            diff[r + 1] -= x;

            items[i][0] = l;
            items[i][1] = r;
            items[i][2] = x;
        }
        long acc = 0;
        for (int i = 1; i <= n; i++) {
            acc += diff[i];
            arr[i] = acc;
        }

        long ans = Long.MAX_VALUE / 10;
        SparesTable table = new SparesTable(arr, Math::max);
        for (int i = 0; i < q; i++) {
            int[] e = items[i];
            int l = e[0], r = e[1], x = e[2];

            long tmax = table.query(l, r) - x;
            if (l > 1) {
                tmax = Math.max(tmax, table.query(1, l - 1));
            }
            if (r < n) {
                tmax = Math.max(tmax, table.query(r + 1, n));
            }

            ans = Math.min(ans, tmax);
        }

        System.out.println(ans);

    }

    static
    class SparesTable {

        long[][] tables;
        BiFunction<Long, Long, Long> callback;

        public SparesTable(long[] arr, BiFunction<Long, Long, Long> callback) {
            int n = arr.length;
            int m = (int)(Math.log(n) / Math.log(2) + 1);
            tables = new long[m][n];
            this.callback = callback;

            for (int i = 0; i < n; i++) {
                tables[0][i] = arr[i];
            }
            for (int i = 1; i < m; i++) {
                int half = 1 << (i - 1);
                for (int j = 0; j + half < n; j++) {
                    tables[i][j] = callback.apply(tables[i - 1][j], tables[i - 1][j + half]);
                }
            }
        }

        // 闭闭区间
        long query(int l, int r) {
            int t = (int)(Math.log(r - l + 1) / Math.log(2));
            return callback.apply(tables[t][l], tables[t][r - (1 << t) + 1]);
        }

    }

}


写在最后

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值