Blue Bridge Cup AcWing learning notes 4-1 learning of enumeration (with relevant Blue Bridge real questions: concatenated interval number, increasing triplet, sum of special numbers) (Java)

Posted by Elusid on Mon, 07 Mar 2022 09:10:43 +0100

Students who participate in the blue bridge cup can pay attention to the blogger. The blogger is also preparing the Blue Bridge Cup and can brush questions with the blogger's blog.

Blue Bridge Cup

My AcWing

The title and pictures are from the counseling class of group ab of Blue Bridge Cup C + +

enumeration

Enumeration, as the name suggests, is to enumerate all possible answers one by one, and then determine the final answer according to the conditions.

Attach today's AcWing calendar 😂
No woman in my heart, coding nature God! Blue Bridge Cup, go!

The fourth 2013 Blue Bridge Cup

AcWing 1210. Consecutive interval number

JavaB group question 10

Find the number of subintervals that can become a continuous interval for an interval

Violence enumeration (timeout)

Time complexity O ( N 3 l o g N ) O(N^3logN) O(N3logN)

Using sorting.

AcWingTLE only passed 4 / 10 of the data, and the Blue Bridge Cup only passed 2 / 5 of the data, with a full score of 100 and only 40 points.

One thing to note: AcWing's data range 1 ≤ N ≤ 10000 1≤N≤10000 1 ≤ N ≤ 10000, while the test range of Blue Bridge Cup 1 ≤ N ≤ 50000 1≤N≤50000 1 ≤ N ≤ 50000, when we open the array, we should open it to 50010, which will be safer.

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

public class Main {

    static final int N = 50010;
    static int[] a = new int[N];
    static int[] backup = new int[N]; // Copy array

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                backup = Arrays.copyOf(a, a.length); // Save data in copy array
                Arrays.sort(a, i,j + 1); // Sort intervals
                boolean flag = true;
                for (int k = i; k < j; k++) {
                    if (a[k + 1] - a[k] != 1) {
                        flag = false;
                        break;
                    }
                }
                if (flag) res++;
                a = Arrays.copyOf(backup, backup.length); // Restore initial array state a
            }
        }
        System.out.println(res);
    }
}

Mathematical law optimization (AC)

Time complexity O ( N 2 ) O(N^2) O(N2)

We find a number: [8, 1, 2, 3, 4, 5, 10], consecutive interval [ i , j ] [i, j] [i,j] is the second number ~ the sixth number. The maximum value of the consecutive interval is 5 and the minimum value is 1. We find a formula: m a x − m i n = j − i max - min = j - i max − min=j − i. as long as a number satisfies this formula, it must be a consecutive interval.

import java.util.Scanner;

public class Main {

    static final int N = 50010, INF = 100000000; // INF is defined as infinity, as long as it is greater than N
    static int[] a = new int[N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        int res = 0;
        for (int i = 0; i < n; i++) { // Enumeration interval left endpoint
            int max = -INF, min = INF;
            for (int j = i; j < n; j++) { // Enumeration interval right endpoint
                max = Math.max(max, a[j]);
                min = Math.min(min, a[j]);
                if (max - min == j - i) res++;
            }
        }
        System.out.println(res);
    }
}

True topic of the 9th 2018 Blue Bridge Cup

AcWing 1236. Incremental triplet

JavaB group question 6

Violence enumeration (timeout)

Time complexity O ( N 3 ) O(N^3) O(N3)

AcWingTLE only passed 6 / 12 data and the Blue Bridge Cup only passed 5 / 8 data. The full score was 100 and only 62 points were obtained.

import java.util.Scanner;

public class Main {

    static final int N = 100010;
    static int[] a = new int[N];
    static int[] b = new int[N];
    static int[] c = new int[N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) a[i] = sc.nextInt();
        for (int i = 0; i < n; i++) b[i] = sc.nextInt();
        for (int i = 0; i < n; i++) c[i] = sc.nextInt();
        
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                for (int k = 0; k < n; k++) {
                    if (a[i] < b[j] && b[j] < c[k]) res++;
                }
            }
        }
        System.out.println(res);
    }
}

Optimization: we only enumerate one array. We can enumerate array B: A i A_{i} Ai​ < < < B j B_{j} Bj​ < < < C k C_{k} Ck = > for each B j B_{j} Bj # the requirements are: ① how many numbers in array A are less than B j B_{j} Bj # ② how many numbers in the C array are greater than B j B_{j} Bj​

Prefix and optimization (AC)

Time complexity O ( N ) O(N) O(N)

less than B j B_{j} The number of Bj can be expressed as: [ 0 , [0, [0, B j B_{j} Bj​ − 1 ] - 1] − 1], define an array cnt, cnt[i] indicates how many times the value of I appears in array A, for (int i = 0; I < n; I + +) cnt [A [i]] + +; cnt is our original array, and s is our prefix and array: s [ i ] = c n t [ 0 ] + c n t [ 1 ] + . . . + c n t [ i ] s[i] = cnt[0] + cnt[1] + ... + cnt[i] s[i]=cnt[0]+cnt[1]+...+cnt[i], s [i] indicates how many times 0~i appear in A, so s [ s[ s[ B j B_{j} Bj​ − 1 ] - 1] − 1] is how many numbers in array A are less than B j B_{j} Bj​; Similarly, you can calculate how many numbers in the C array are greater than B j B_{j} Bj​.

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

public class Main {

    static final int N = 100010;
    static int[] a = new int[N];
    static int[] b = new int[N];
    static int[] c = new int[N];
    static int[] as = new int[N]; // as[i] indicates how many numbers in a [] are less than b[i]
    static int[] cs = new int[N]; // cs[i] indicates how many numbers in c [] are greater than b[i]
    static int[] cnt = new int[N];
    static int[] s = new int[N]; // Prefix and array

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) a[i] = sc.nextInt() + 1; // Here + 1 is required to prevent the array from crossing the boundary
        for (int i = 0; i < n; i++) b[i] = sc.nextInt() + 1; // Because there are subsequent operations with subscript-1
        for (int i = 0; i < n; i++) c[i] = sc.nextInt() + 1; // If there are several zeros in the array, it will be out of bounds

        // as []
        for (int i = 0; i < n; i++) cnt[a[i]]++; // Record the number of occurrences of a[i]
        for (int i = 1; i < N; i++) s[i] = s[i - 1] + cnt[i]; // Prefix and formula
        for (int i = 0; i < n; i++) as[i] = s[b[i] - 1]; // Record the quantity less than b[i]

        // Initialize array to 0
        Arrays.fill(cnt, 0);
        Arrays.fill(s, 0);

        // Find cs []
        for (int i = 0; i < n; i++) cnt[c[i]]++; // Record the number of occurrences of c[i]
        for (int i = 1; i < N; i++) s[i] = s[i - 1] + cnt[i]; // Prefix and formula
        for (int i = 0; i < n; i++) cs[i] = s[N - 1] - s[b[i]];  // Record the quantity greater than b[i]

        long res = 0;
        // Enumerate each b[i]
        for (int i = 0; i < n; i++) res += (long)as[i] * cs[i];
        System.out.println(res);
    }
}

True topic of the 10th 2019 Blue Bridge Cup

AcWing 1245. Sum of special numbers

JavaB group question 6

This question is very simple. You only need to enumerate the number of digits of each number and then make if judgment.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int res = 0;
        for (int i = 1; i <= n; i++) {
            int x = i;
            while (x > 0) {
                int t = x % 10; // Take out the bits of x
                x /= 10; // Delete the bits of x
                if (t == 2 || t == 0 || t == 1 || t == 9) {
                    res += i;
                    break;
                }

            }
        }
        System.out.println(res);
    }
}

Use the contains method in String to determine whether a String is included.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int res = 0;
        for (int i = 1; i <= n; i++) {
            if (String.valueOf(i).contains("2") || String.valueOf(i).contains("0") 
             || String.valueOf(i).contains("1") || String.valueOf(i).contains("9")) {
                res += i;
            }
        }
        System.out.println(res);
    }
}

If you don't understand the code, you can comment below

Topics: Java Algorithm dfs