• Codeforces Round 909 (Div. 3) 题解 A-E


    A - Game with Integers

    原题链接

    题目描述
    给定一个整数NAB都可以对这个整数进行加一或者减一操作,从A开始,如果A可以让N3整除,那么A获胜,如果10步之内A没有获胜,那么B获胜。

    思路:思维

    • 如果N3的倍数,那么A永远无法获胜,否则AN进行加一或者减一则必胜。
    public static void solve() throws IOException{
        int n = readInt();
        if (n % 3 == 0) {
            printWriter.println("Second");
        } else {
            printWriter.println("First");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    B - 250 Thousand Tons of TNT

    原题链接

    题目描述
    N个箱子从左到右排成一排,第i个箱子重 a i a_i ai 吨。现在你可以使用K辆卡车,从左到右依次将箱子装入卡车,但是每辆卡车上装入的箱子数量必须一致,但是你想让这K辆卡车的其中两辆卡车所装货物重量之差尽可能大,求出这个最大差值。

    思路:前缀和+枚举

    • 先枚举每辆卡车所装箱子的数量:只需要枚举数量为 1 ≤ i ≤ n 2 1 \leq i \leq \frac{n}{2} 1i2n 的箱子,因为数量大于 n 2 \frac{n}{2} 2n后方案肯定不可行,数量为 n n n时结果肯定为 0 0 0
    • 再枚举每辆卡车所装箱子的重量之和,求出最大差值。
    public static void solve() throws IOException{
        int n = readInt();
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            arr[i] = readInt();
        }
        long[] pre = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            pre[i] = pre[i - 1] + arr[i];
        }
        long res = 0;
        for (int i = 1; i <= n / 2; i++) { // 枚举每辆卡车上的箱子数量
            if (n % i == 0) {
                long curMax = Long.MIN_VALUE, curMin = Long.MAX_VALUE;
                for (int j = i; j <= n; j += i) { // 枚举每辆卡车上的箱子重量之和
                    curMax = Math.max(pre[j] - pre[j - i], curMax);
                    curMin = Math.min(pre[j] - pre[j - i], curMin);
                }
                res = Math.max(curMax - curMin, res);
            }
        }
        printWriter.println(res);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    C - Yarik and Array

    原题链接

    题目描述
    有一个长度为n的数组a,你需要找出一个子数组,且其中的元素都是奇偶相邻的,并且这个子数组的和最大,请求出这个最大和。

    思路:动态规划

    • dp数组的定义为:以第i个元素结尾所能构成的最大子数组的和。
    public static void solve() throws IOException{
        int n = readInt();
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++) arr[i] = readInt();
        int[] dp = new int[n + 1];
        dp[1] = arr[1];
        for (int i = 2; i <= n; i++) {
        	// 奇偶性不同,在取前面的元素和不取前面元素中得最大值
            if ((arr[i - 1] & 1) != (arr[i] & 1)) {
                dp[i] = Math.max(arr[i], dp[i - 1] + arr[i]);
            } else {// 奇偶性相同,那么以第 i个元素结尾所能构成的最大子数组的和只能是arr[i]本身
                dp[i] = arr[i];
            }
        }
        int max = Integer.MIN_VALUE;
        for (int i = 1; i <= n; i++) {
            max = Math.max(max, dp[i]);
        }
        printWriter.println(max);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    D - Yarik and Musical Notes

    原题链接

    题目描述
    有一个长度为n的数组a和数组b,数组b的每个元素为 2 a i 2^{a_i} 2ai,你需要找出总共有多少对 b i b j = b j b i ( i ≤ j ) b_i^{b_j} = b_j^{b_i}(i \leq j) bibj=bjbi(ij)

    思路:组合数学

    • 原式为 2 a i 2 a j = 2 a j 2 a i 2^{a_i^{2^{a_j}}} = 2^{a_j^{2^{a_i}}} 2ai2aj=2aj2ai a i ∗ 2 a j = a j ∗ 2 a i a_i * 2^{a_j} = a_j * 2^{a_i} ai2aj=aj2ai,再得 a i a j = 2 a j − a i \frac{a_i}{a_j} = 2^{a_j - a_i} ajai=2ajai,那么 ① a i = a j a_i = a_j ai=aj a i = 1 , a j = 2 a_i=1,a_j=2 ai=1,aj=2 a i = 2 , a j = 1 a_i=2,a_j=1 ai=2,aj=1,最后进行组合计数即可。
    public static void solve() throws IOException{
        int n = readInt();
        Map<Integer, Long> map = new HashMap<>();
        for (int i = 1; i <= n; i++) {
            int a = readInt();
            map.put(a, map.getOrDefault(a, 0l) + 1);
        }
        long res = 0;
        for (Long val : map.values()) {
            res += val * (val - 1) / 2;// 情况一
        }
        // 情况二和三
        res += (map.getOrDefault(1, 0l) * map.getOrDefault(2, 0l));
        printWriter.println(res);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    E - Queue Sort

    原题链接

    题目描述
    给定一个长度为n的数组a,你需要将其变为不递减数组。你可以进行以下操作多次:将第一个元素移至数组末尾,再将这个元素与其前面的元素对比,直至该元素严格大于他前面的元素或者成为第一个元素。如果无法将该数组变为不递减数组,输出-1,否则输出将其变为不递减数组的最少操作数。

    思路:观察

    • 观察可得,如果数组中最小的元素后面出现了降序的情况,那么永远无法将数组变为不递减数组,否则输出最小的元素前面有多少个比它大的元素。
    public static void solve() throws IOException{
        int n = readInt();
        int min = Integer.MAX_VALUE; // 数组中的最小元素
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = readInt();
            min = Math.min(min, arr[i]);
        }
        int idx = 0;// 数组中的最小元素第一次出现的位置
        for (int i = 0; i < n; i++) {
            if (arr[i] == min) {
                idx = i;
                break;
            }
        }
        boolean f = true;// 最小元素后面是否不递减
        for (int i = idx + 1; i < n; i++) {
            if (arr[i] < arr[i - 1]) {// 出现降序
                f = false;
                break;
            }
        }
        if (!f) {
            printWriter.println(-1);
        } else {
            int cnt = 0; // 最小的元素前面有多少个比它大的元素
            for (int i = 0; i < n; i++) {
                if (arr[i] > min) {
                    cnt++;
                } else {
                    break;
                }
            }
            printWriter.println(cnt);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    ubuntu20.04 安装TensorRT,解决依赖问题
    TypeScript的函数和类
    分组卷积/转置卷积/空洞卷积/反卷积/可变形卷积/深度可分离卷积/DW卷积/Ghost卷积/
    清晰易懂IoC
    java毕业设计房屋租赁平台mybatis+源码+调试部署+系统+数据库+lw
    MySQL之DML
    《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(5)-Fiddler监控面板详解
    【C刷题】day2
    进程和线程的区别 && 线程之间共享的资源
    部署K3s工作节点 --- 树莓派
  • 原文地址:https://blog.csdn.net/xiaoqian7758258/article/details/134478436