河南农业大学2023春蓝桥杯赛前训练第六场

B 空调遥控

差分 + 前缀和

-p <= a[i] - K <= p
-p - a[i] <= -K <= p - a[i]
a[i] - p <= K <= a[i] + p

p 和 a[i] 是给定的,我们就用差分,求出每个人适宜的温度区间,覆盖表示
0 1 2 3 4 5 6 7 8 K
2 1 1 1 0 -1 0 -1 cnt

K是温度,cnt是差分数组,前缀和表示当温度为 K 时,有多少个 a[i] 的舒适区间覆盖此温度

/**
 * @author :Changersh
 * @date : 2023/3/31 19:29
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int T, N = (int) 2e6 + 10, n, p, l, r, x, mx, ans;
    private static int[] s = new int[N];
    private static String[] sp;

    public static void main(String[] args) throws IOException {
        BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
        sp = sc.readLine().split(" ");
        n = Integer.parseInt(sp[0]);
        p = Integer.parseInt(sp[1]);
        sp = sc.readLine().split(" ");
        for (int i = 0; i < n; i++) {
            x = Integer.parseInt(sp[i]);
            l = Math.max(0, x - p);
            r = x + p;

            s[l] += 1;
            s[r + 1] -= 1;
        }


        for (int i = 1; i <= n; i++) {
            s[i] += s[i - 1];
            if (s[i] > mx) {
                mx = s[i];
            }
        }

        System.out.println(mx);
    }
}

D 优美字符串

模拟

从第一个元素开始,统计和它后面一个元素相等的个数

/**
 * @author :Changersh
 * @date : 2023/3/31 18:59
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int N = 2010, n, k, x, y, T;
    private static char[] a;

    public static void main(String[] args) throws IOException {
        BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
        T = Integer.parseInt(sc.readLine());
        while (T-- > 0) {
            int ans = 0;
            a = sc.readLine().toCharArray();
            n = a.length;

            for (int i = 0; i < n - 1; i++) if (a[i] == a[i + 1]) ans++;
            System.out.println(ans + n);
        }
    }
}

E 数字游戏

数学

公式可以推出来
偶数个 1
最低位是 0:1010–10–11–1–0 2*cnt
最低位是 1:1001–1–0 cnt 这个算错了
1111–111–110–10–11–1–0 …------- (cnt - 1) * 2
10111–111–110–10–11–1–0 (以防万一多算几个,发现是 第二个)

奇数个 1
最低位是 0:1110–1111–111–110–10–11–1–0 2 * cnt + 1
最低位是 1:1101–1100–100–101–1–0 2 * cnt - 1

/**
 * @author :Changersh
 * @date : 2023/4/4 8:56
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int T, N = (int) 1e6 + 10, x, cnt = 0, ans;
    private static boolean ck;

    public static void main(String[] args) throws IOException {
        T = sc.nextInt();

        while (T-- > 0) {
            cnt = 0;
            x = sc.nextInt();
            if ((x & 1) == 1) ck = true;
            else ck = false;
            while (x > 0) {
                if ((x & 1) == 1) cnt++;
                x >>= 1;
            }


            if ((cnt & 1) == 1) { // 奇数个 1
                if (ck) ans = 2 * cnt - 1;
                else ans = 2 * cnt + 1;
            } else {
                if (ck) ans = (cnt - 1) * 2;
                else ans = 2 * cnt;
            }

            pw.println(ans);
        }

        pw.close();
    }
}

F 体操队形

dfs

方案数只有 10 个,暴力搜索
dfs的判断条件:该点是否访问过? & 该点的后面一个点是否访问过?

/**
 * @author :Changersh
 * @date : 2023/3/31 20:22
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int N = 20, T, n, ans;
    private static int[] a = new int[N];
    private static boolean[] vis = new boolean[N];
    private static String[] sp;
    public static void main(String[] args) throws IOException {
        BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter pw = new BufferedWriter(new OutputStreamWriter(System.out));

        n = Integer.parseInt(sc.readLine());
        sp = sc.readLine().split(" ");
        for (int i = 0; i < n; i++) a[i + 1] = Integer.parseInt(sp[i]);

        dfs(0);

        pw.write(("" + ans));
        pw.close();
    }

    private static void dfs(int u) {
        if (u >= n) {
            ans++;
            return;
        }

        for (int i = 1; i <= n; i++) {
            if (vis[i]) continue;
            if (vis[a[i]]) break; // 本该在 i 后面的选过了
            vis[i] = true;
            dfs(u + 1);
            vis[i] = false;
        }
    }
}

H 分组

二分答案

二分人数最多的组的人数

/**
 * @author :Changersh
 * @date : 2023/4/4 8:56
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int N = (int) 1e5 + 10, m, n, ans = 0x3f3f3f3f, l = 1, r, x, mx;
    private static int[] a = new int[N];
    public static void main(String[] args) throws IOException {

        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i < n; i++) {
            x = sc.nextInt();
            a[x]++;
            mx = Math.max(mx, a[x]);
        }
        r = mx + 1;
        while (l < r) {
            int mid = l + ((r - l) >> 1);
            if (check(mid)) {
                r = mid;
                ans = Math.min(ans, mid);
            } else l = mid + 1;
        }
        if (check(ans)) pw.println(("" + ans));
        else pw.println("-1");
        pw.close();
    }

    private static boolean check(int x) {
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
            cnt += a[i] / x + (a[i] % x == 0 ? 0 : 1);
        }

        return cnt <= m;
    }
}

I 跳跳跳

区间dp,记忆化搜索

发现在任意时刻,已经跳的区间都是一个联通块(区间)
考虑把数组复制一份,贴在原数组后面,构成环形数组
f[l][r]=max(f[l+1][r]+a[l]∗len,f[l][r−1]+a[r]∗len)
len 是区间长度

/**
 * @author :Changersh
 * @date : 2023/4/4 8:56
 */

import java.io.*;
import java.util.*;
import java.lang.*;

public class Main {
    private static int T, N = 4010, n;
    private static long ans = 0;
    private static int[] a = new int[N];
    private static long[][] f = new long[N][N];

    public static void main(String[] args) throws IOException {
        n = sc.nextInt();

        for (int i = 1; i <= n; i++) {
            a[i] = sc.nextInt();
            a[i + n] = a[i]; // 复制一份,构造环形数组
        }
        
        // 对每个点都进行一次dfs,找到最大值
        for (int i = 1; i <= n; i++) ans = Math.max(ans, dfs(i, i + n - 1));
        
        pw.println(ans);
        pw.close();
    }

    private static long dfs(int l, int r) {
        if (l == r) return a[l];
        if (f[l][r] != 0) return f[l][r];
        
        long len = r - l + 1;
        
        return f[l][r] = Math.max(dfs(l + 1, r) + len * a[l], dfs(l, r - 1) + len * a[r]);
    }
}

你可能感兴趣的:(蓝桥杯,java,职场和发展)