华为OD真题2023

具体题的内容站内自行搜索-华为od机试真题2023

这里不贴链接了,防止侵权什么的

除了最后3个经过验证,其他的不保证全通过率

只是自己随便写了些题目的答案,有些是在别人专栏内不足100%的基础上优化的,自行斟酌吧
都是打工的兄弟,就不开专栏了,准备期间的题答案都贡献出来,一把梭哈

1.统一限载货物数最小值

private static void minGoods() {
    Scanner sc = new Scanner(System.in);
    int len = sc.nextInt();
    int[] arr = new int[len];
    for (int i = 0; i < len; i++) {
        arr[i] = sc.nextInt();
    }
    List<Integer> wetGoods = new LinkedList<>();
    List<Integer> dryGoods = new LinkedList<>();

    int drySum = 0, wetSum = 0;
    for (int i = 0; i < len; i++) {
        int temp = sc.nextInt();
        if (temp == 0) {
            dryGoods.add(arr[i]);
            drySum += arr[i];
        } else {
            wetGoods.add(arr[i]);
            wetSum += arr[i];
        }
    }

    int k = sc.nextInt();
    // 本质是求k量车,容量最小是多少时,可以装下所有货物
    int min = Math.max(dryGoods.size() != 0 ? drySum / dryGoods.size() : 0,wetGoods.size() != 0 ? wetSum / wetGoods.size() : 0);
    int max = Math.max(drySum, wetSum);

    int res = max;
    while (min <= max) {
        int mid = (min + max) / 2;
        if (judgeVolume(mid, k, dryGoods, wetGoods, drySum, wetSum)) {// 可以放得下
            res = mid;
            max = mid - 1;
        } else {
            min = mid + 1;
        }
    }
    System.out.println(res);
}

// vol的容量,能不能装下这些货物
private static boolean judgeVolume(int vol, int k, List<Integer> dryGoods, List<Integer> wetGoods, int drySum, int wetSum) {
    Collections.sort(dryGoods);
    Collections.sort(wetGoods);
    int drySize = dryGoods.size();
    int wetSize = wetGoods.size();

    if (drySize > 0 && vol < dryGoods.get(drySize - 1)) return false;
    if (wetSize > 0 && vol < wetGoods.get(wetSize - 1)) return false;
    Set<Integer> dryIndex = new HashSet<>();
    for (int i = 0; i < k && drySum > 0; i++) {
        int temp = vol;
        for (int j=drySize-1;j>=0 && temp > 0;j--){
            int good = dryGoods.get(j);
            if(!dryIndex.contains(j) && good >= 0 && good <= temp){
                temp -= good;
                drySum -= good;
                dryIndex.add(j);
            }
        }
    }
    Set<Integer> wetIndex = new HashSet<>();
    for (int i = 0; i < k && wetSum > 0; i++) {
        int temp = vol;
        for (int j=wetSize-1;j>=0 && temp > 0;j--){
            int good = wetGoods.get(j);
            if(!wetIndex.contains(j) && good >= 0 && good <= temp){
                temp -= good;
                wetSum -= good;
                wetIndex.add(j);
            }
        }
    }

    return drySum == 0 && wetSum == 0;

}

2.几何平均值最大子数组

private static void maxSub() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int l = sc.nextInt();
    double[] nums = new double[n];

    for (int i = 0; i < n; i++) {
        //            nums[i] = random.nextInt(20);
        nums[i] = sc.nextDouble();
    }
    System.out.println(Arrays.toString(nums));

    // 暴力做法,复杂度n2,也就是10^10
    double max = 0;
    int lIndex = -l - 1;
    int rIndex = 0;
    for (int i = 0; i < n - l + 1; i++) {
        double mul = 1;
        double tem;
        for (int j = i; j < n; j++) {
            mul = mul * nums[j];
            if (j - i + 1 < l) continue;
            tem = Math.pow(mul, (double) 1 / (j - i + 1));

            // 相等
            if (tem - max > 0.000001) {
                max = tem;
                lIndex = i;
                rIndex = j;
            }
        }
    }
    System.out.println(lIndex + " " + (rIndex - lIndex + 1) + " " + max);
}

3.士兵过河

/**
     * 1:1个士兵过河,用时t1
     * 2:2个士兵过河,用时t_max
     * 3:3个士兵过河,用时10 * t_min
     * <p>
     * 多个士兵时,最少俩士兵一起,因为用时短的不算时间
     * 如果3个士兵,那肯定是2个用时最长的配一个用时最短的,且满足三人用时最短
     * 6个士兵,如何渡河?
     */
private static void soldierRiver() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int t = sc.nextInt();
    int[] arr = new int[n];
    for (int i = 0; i < n; i++) {
        arr[i] = sc.nextInt();
    }
    String s = crossTheRiver(n, t, arr);
    System.out.println(s);
}
// 返回最多存活士兵+最短用时

/**
     * 说明
     * 0  1  2  3  4  5  6  7  8
     * 12 13 15 20 20 25 35 99 99
     * dp[0] = 12
     * dp[1] = 13
     * dp[2] = 15+12+13 = 40
     * dp[3] = 13 + 12 + 20 + 13 * 2 = 71
     * dp[4] = 103 / 40 + 12 + 20 + 26 = 98
     * dp[5] = 98 + 37 = 135 / 71 + 12 + 25 + 26 = 134
     * dp[6] = 134 + 47 = 181 / 98 + 12 + 35 + 26 = 171
     * dp[7] = 171 + 111 = 282 / 134 + 12 + 99 + 26 = 271 / 134 + 12 + 120 = 266
     * dp[8] = 266 + 111 = 377 / 171 + 12 + 99 + 26 = 308 / 171 + 12 + 120 = 303
     */
public static String crossTheRiver(int n, int t, int[] a) {
    Arrays.sort(a);
    if (a[0] > t) {
        return "0 0";
    }
    // 士兵数小于 2
    if (n < 2) {
        return "1 " + a[0];
    }

    int[] dp = new int[n];
    dp[0] = a[0];
    dp[1] = a[1];
    if (dp[1] > t) {
        return "1 " + dp[0];
    }

    for (int i = 2; i < n; i++) {
        int a1 = dp[i - 1] + a[0] + Math.max(a[0], a[i]);
        // a[0]和a[1]得开回来
        int a2 = dp[i - 2] + a[0] + Math.max(a[i - 1], a[i]) + 2 * a[1];
        if (10 * a[0] < a2 - dp[i - 2] - a[0]) a2 = dp[i - 2] + a[0] + 10 * a[0];

        dp[i] = Math.min(a1, a2);
        if (dp[i] > t) {
            //System.out.println(Arrays.toString(dp));
            return i + " " + dp[i - 1];
        }
    }
    //System.out.println(Arrays.toString(dp));
    return n + " " + dp[n - 1];
}

4.任务混部/最少服务器数

private static void taskDeploy() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int[][] nums = new int[n][3];

    for (int i = 0; i < n; i++) {
        nums[i][0] = sc.nextInt();
        nums[i][1] = sc.nextInt();
        nums[i][2] = sc.nextInt();
    }

    int res = 0;
    for (int i = 0; i < n; i++) {
        int timeStart = nums[i][0];
        int timeEnd = nums[i][1];
        int temp = 0;
        for (int j = 0; j < n; j++) {
            if (!(nums[j][0] >= timeEnd || nums[j][1] < timeStart)) {
                temp += nums[j][2];
            }
        }
        res = Math.max(temp, res);
    }
    System.out.println(res);
}

5.垃圾短信发送者

private static void garbageText() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int[][] texts = new int[n][2];
    for (int i = 0; i < n; i++) {
        texts[i][0] = sc.nextInt();
        texts[i][1] = sc.nextInt();
    }
    int id = sc.nextInt();

    // in:接收短信数量 out:发送短信数量 mapDiff:A发送给x和接收x短信的差值
    int in = 0;
    int out = 0;
    Map<Integer, Integer> mapDiff = new HashMap<>();
    Set<Integer> sets = new HashSet<>();
    for (int i = 0; i < n; i++) {
        int startId = texts[i][0];
        int endId = texts[i][1];

        if (startId == id) {
            out++;
            Integer nums = mapDiff.getOrDefault(endId, 0);
            mapDiff.put(endId, nums + 1);
        }

        if (endId == id) {
            in++;
            Integer nums = mapDiff.getOrDefault(startId, 0);
            mapDiff.put(startId, nums - 1);
            sets.add(startId);// 发送过短信给A的id
        }
    }
    int diff = out - in;
    int sizeDiff = mapDiff.size() - sets.size();
    if (diff > 10 || sizeDiff > 5) {
        System.out.println("true " + sizeDiff + " " + diff);
        return;
    }

    for (Integer val : mapDiff.values()) {
        if (val > 5) {
            System.out.println("true " + sizeDiff + " " + diff);
            return;
        }
    }

    System.out.println("false " + sizeDiff + " " + diff);
}

6.信号发射和接收

private static void singleLine() {
    Scanner sc = new Scanner(System.in);
    int m = sc.nextInt();
    int n = sc.nextInt();
    int[][] matrix = new int[m][n];

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = sc.nextInt();
        }
    }

    /**
         * 分析
         * 只能接受左边或者上边来的信号
         * 左边第一个不小于自己高的天线 +(左边声明一个最大高度,不断遍历时迭代,低于这个高度的不统计,大于等于的更新高度和累加信号数)
         */
    // 东西向
    int[][] row = new int[m][n];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            int index = j - 1;
            int tempMax = 0;
            int nums = 0;
            while (index >= 0 && matrix[i][index] < matrix[i][j]) {
                if (matrix[i][index] > tempMax) {
                    nums++;
                    tempMax = matrix[i][index];
                }
                index--;
            }
            if (index >= 0 && matrix[i][index] >= matrix[i][j]) nums++;
            row[i][j] = nums;
        }
    }
    // 南北向
    int[][] col = new int[m][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            int index = j - 1;
            int tempMax = 0;
            int nums = 0;
            while (index >= 0 && matrix[index][i] < matrix[j][i]) {
                if (matrix[index][i] > tempMax) {
                    nums++;
                    tempMax = matrix[index][i];
                }
                index--;
            }
            if (index >= 0 && matrix[index][i] == matrix[j][i]) nums++;
            col[j][i] = nums;
        }
    }
    System.out.println(m + " " + n);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = row[i][j] + col[i][j];
            System.out.print(matrix[i][j]);
            if (i != m - 1 || j != n - 1) {
                System.out.print(" ");
            }
        }
    }

}

7.红黑图—将不合格的剔除即可行

private static void redBlackGraph() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();// nodes num
    int m = sc.nextInt();// edge num
    List<int[]> edges = new LinkedList<>();
    for (int i = 0; i < m; i++) {
        int s = sc.nextInt();
        int e = sc.nextInt();
        int[] edge = {s, e};
        edges.add(edge);
    }

    int allPath = (int) Math.pow(2, n);
    int res = allPath;
    for (int i = 0; i < allPath; i++) {
        // 规定1红,0黑
        for (int[] edge : edges) {
            int start = 1 << edge[0];
            int end = 1 << edge[1];
            if ((start & i) != 0 && (end & i) != 0) {
                res--;
                break;
            }
        }
    }
    System.out.println(res);
}

8.linux发行版的数量

private static void linuxNums() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int[][] nums = new int[n][n];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            nums[i][j] = sc.nextInt();
        }
    }

    int max = 0;
    Set<Integer> maxIndes = new HashSet<>();
    for (int i = 0; i < n && !maxIndes.contains(i); i++) {
        Set<Integer> visited = new HashSet<>();
        Deque<Integer> deque = new LinkedList<>();
        deque.addLast(i);
        while (!deque.isEmpty()) {
            int index = deque.pollFirst();
            visited.add(index);
            for (int j = 0; j < n; j++) {
                if (nums[index][j] == 1 && !visited.contains(j)) {
                    deque.addLast(j);
                }
            }
        }
        if (visited.size() > max) {
            max = visited.size();
            maxIndes = visited;
        }
    }
    System.out.println(max);
}

9.天然蓄水库

目前样例全过

// 1 2 3---0
// 1 9 6 2 5 4 9 3 7---1 6:19
// 1 8 6 2 5 4 8 3 7---1 6:15
// 1 7 3 10 10---1 3:4
// 4 3 2 0 2 3---1 5:5
// 1 2 2 0 2 1 2 0 2 2---2 8:5
private static void natureWater() {
    Scanner sc = new Scanner(System.in);
    String arr = sc.nextLine();
    String[] s = arr.split(" ");
    int[] nums = new int[s.length];

    nums[0] = Integer.parseInt(s[0]);
    for (int i = 1; i < s.length; i++) {
        nums[i] = Integer.parseInt(s[i]);
    }

    // 从前往后找,如果左<右,那就截止到右边即可
    // 如果左 > 右,继续往后走,找到后面最高的那个
    int len = nums.length;
    int left = 0;
    int maxArea = 0;
    // 记录最大面积时左右坐标
    int p = 0, q = 0;
    while (left + 1 < len) {
        if (nums[left] < nums[left + 1]) {
            left++;
            continue;
        }
        int right = left + 1;
        int maxIndex = left + 1;
        // 找到比left位置高/比其低的里面最高的坐标
        while (right < len && nums[left] >= nums[right]) {
            maxIndex = nums[right] >= nums[maxIndex] ? right : maxIndex;
            right++;
        }
        // 处理右边比left位置高的坐标
        if (right < len && nums[left] <= nums[right]) maxIndex = right;

        int area = getArea(nums, left, maxIndex);
        if (maxArea < area) {
            maxArea = area;
            p = left;
            q = maxIndex;
        }
        maxArea = Math.max(maxArea, area);

        left = maxIndex;
    }
    // 处理左右两边界坐标,看能否向内走
    int min = Math.min(nums[p], nums[q]);
    while (p < len - 1 && min <= nums[p + 1]) p++;
    while (q > 0 && min <= nums[q - 1]) q--;

    if (maxArea == 0) System.out.println(0);
    else System.out.println(p + " " + q + ":" + maxArea);
}

private static int getArea(int[] nums, int left, int right) {
    int area = 0;
    int height = Math.min(nums[left], nums[right]);
    for (int i = left + 1; i < right; i++) {
        area += (height - nums[i]);
    }
    return area;
}

10.狼羊过河

private static void wolfAndSheepRiver() {
    Scanner sc = new Scanner(System.in);
    int m = sc.nextInt();// 羊
    int n = sc.nextInt();// 狼
    int x = sc.nextInt();// 容量

    System.out.println(computeRiver(m, n, x));
}

private static int computeRiver(int m, int n, int x) {
    if (m + n <= x) return 1;
    // m <= x时,需要考虑
    // 1:x=10,m=5,n=15
    if (m <= x) {
        if (n >= x + m) return 0;
        return (m + n - 1) / x + 1;
    }

    if (n >= m - 1) return 0;

    if (n == m - 2) {
        if ((x % 2) == 0) return (m + n) / x + 1;
        else return (m + n - 3) / (x - 1) + 1;
    }
    return (m + n - 1) / x + 1;
}

11.递增字符串

private static void minFlipsMonoIncr() {
    Scanner sc = new Scanner(System.in);
    String s = sc.nextLine();

    int n = s.length();
    int dp0 = 0, dp1 = 0;
    for (int i = 0; i < n; i++) {
        char c = s.charAt(i);
        int dp0New = dp0, dp1New = Math.min(dp0, dp1);
        if (c == 'B') {
            dp0New++;
        } else {
            dp1New++;
        }
        dp0 = dp0New;
        dp1 = dp1New;
    }
    System.out.println(Math.min(dp0, dp1));
}

12.最长相似链

class Node {
    String str;
    int num;//到这个字符的链最长多少

    Node(String str) {
        this.str = str;
        this.num = 0;
    }
}

public int longestStrChain(String[] words) {
    Map<Integer, List<Node>> map = new HashMap<>();
    for (int i = 0; i < words.length; i++) {
        List<Node> list = map.getOrDefault(words[i].length(), new LinkedList<>());
        Node node = new Node(words[i]);
        list.add(node);
        map.put(words[i].length(), list);
    }
    PriorityQueue<Integer> queue = new PriorityQueue<>();
    for (Integer key : map.keySet()) {
        queue.add(key);
    }
    int max = 0;
    while (!queue.isEmpty()) {
        int keyL = queue.poll();
        if (queue.isEmpty()) break;
        int keyR = queue.peek();
        if (keyR != keyL + 1) continue;
        List<Node> left = map.get(keyL);
        List<Node> right = map.get(keyR);
        for (Node st1 : left) {
            for (Node st2 : right) {
                if (judge(st1.str, st2.str)) {
                    st2.num = Math.max(st1.num + 1, st2.num);
                    max = Math.max(st2.num, max);
                }
            }
        }
    }
    return max + 1;
}

private boolean judge(String st1, String st2) {
    boolean flag = false;
    int diff = 0;
    for (int i = 0; i < st1.length(); i++) {
        if (st1.charAt(i) != st2.charAt(i - diff)) {
            if (!flag) {
                flag = true;
                diff = 1;
            } else {
                return false;
            }
        }
    }
    return true;
}

13.相似单词

private static void likeWord() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    sc.nextLine();
    // 排序后压缩做key
    Map<String, List<String>> map = new HashMap<>();

    for (int i = 0; i < n; i++) {
        String str = sc.nextLine();
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        String key = Arrays.toString(chars);
        List<String> val = map.getOrDefault(key, new LinkedList<>());
        val.add(str);
        map.put(key, val);
    }
    String word = sc.nextLine();
    char[] chars = word.toCharArray();
    Arrays.sort(chars);
    String key = Arrays.toString(chars);
    List<String> val = map.get(key);
    if (val == null) {
        System.out.println("null");
        return;
    }
    Collections.sort(val);
    int i = 0;
    for (; i < val.size() - 1; i++) {
        System.out.print(val.get(i) + " ");
    }
    System.out.print(val.get(i));

}

14.上班之路

private static void workWay() {
    Scanner sc = new Scanner(System.in);
    int t = sc.nextInt();
    int c = sc.nextInt();
    int n = sc.nextInt();
    int m = sc.nextInt();
    sc.nextLine();
    char[][] graph = new char[n][m];
    int startR = 0;
    int startC = 0;
    int targetR = 0;
    int targetC = 0;
    for (int i = 0; i < n; i++) {
        String str = sc.nextLine();
        graph[i] = str.toCharArray();
        for (int j = 0; j < m; j++) {
            if (graph[i][j] == 'S') {
                startR = i;
                startC = j;
            } else if (graph[i][j] == 'T') {
                targetR = i;
                targetC = j;
            }
        }
    }
    boolean res = findWay(startR, startC, targetR, targetC, graph, t + 1, c, 0);
    System.out.println(res ? "YES" : "NO");
}

private static boolean findWay(int startR, int startC, int targetR, int targetC, char[][] graph, int t, int c, int direct) {
    if (startR == targetR && startC == targetC) return true;
    if (startR < 0 || startC < 0 || startR >= graph.length || startC >= graph[0].length || t < 0) return false;
    if (graph[startR][startC] == '*') c--;
    if (c < 0) return false;
    // 上左下右---1234
    return findWay(startR - 1, startC, targetR, targetC, graph, direct == 1 ? t : t - 1, c, 1) ||
        findWay(startR, startC - 1, targetR, targetC, graph, direct == 2 ? t : t - 1, c, 2) ||
        findWay(startR + 1, startC, targetR, targetC, graph, direct == 3 ? t : t - 1, c, 3) ||
        findWay(startR, startC + 1, targetR, targetC, graph, direct == 4 ? t : t - 1, c, 4);
}

15.最少线段覆盖数量

// 每次找当前选择的范围内最远的就对了
private static void minLineCover() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    sc.nextLine();
    PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
            if (o1[0] != o2[0]) {
                return o1[0] - o2[0];
            } else {
                return o2[1] - o1[1];
            }
        }
    });
    for (int i = 0; i < n; i++) {
        String s = sc.nextLine();
        String[] input = s.split(",");
        int[] arr = new int[2];
        arr[0] = Integer.valueOf(input[0]);
        arr[1] = Integer.valueOf(input[1]);
        queue.add(arr);
    }
    // 开始处理
    int res = 1;
    int[] poll = queue.poll();
    int index = poll[1];
    while (!queue.isEmpty()) {
        int maxRight = index;
        while (!queue.isEmpty() && queue.peek()[0] <= index) {
            maxRight = Math.max(queue.poll()[1], maxRight);
        }
        index = maxRight;
        res++;
    }
    System.out.println(res);
}

16.统计差异值大于相似值二元数组个数

private static void diffBiggerSim() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int[] arr = new int[n];

    for (int i = 0; i < n; i++) {
        arr[i] = sc.nextInt();
    }

    int res = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (compareDiff(arr[i], arr[j])) {
                res++;
            }
        }
    }
    System.out.println(res);
}

private static boolean compareDiff(int a, int b) {
    int flag = 1;
    int diff = 0;
    int sim = 0;
    int max = Math.max(a, b);
    while (flag < max) {
        diff += ((a & flag) ^ (b & flag));
        if ((a & flag) != 0 && (b & flag) != 0) {
            sim += flag;
        }
        flag = flag << 1;
    }

    return diff > sim;
}

17.删除空格

private static void delBlank() {
    Scanner sc = new Scanner(System.in);
    String str = sc.nextLine();
    boolean singleFlag = false;
    boolean isBlank = false;
    char[] chars = str.toCharArray();
    StringBuilder sb = new StringBuilder();

    int i = 0;
    while (i < chars.length) {
        StringBuilder temp = new StringBuilder();
        while (i < chars.length && check(chars[i])) {
            temp.append(chars[i]);
            i++;
        }
        sb.append(temp);
        isBlank = false;
        while (chars[i] == ' ') {
            if (!isBlank) {
                sb.append(' ');
                isBlank = true;
            }
            i++;
        }
        if ((i == chars.length && isBlank) || chars[i] == ',') {
            sb.delete(sb.length() - 1, sb.length());
        }
        singleFlag = false;
        if (!check(chars[i])) {
            singleFlag = true;
            sb.append(chars[i]);
        }
        temp = new StringBuilder();
        while (singleFlag && i < chars.length && !check(chars[i]) && chars[i] != ' ') {
            temp.append(chars[i]);
            i++;
        }
    }
    System.out.println(sb);
    System.out.println(sb.reverse());
}

private static boolean check(char aChar) {
    if ((aChar <= 'Z' && aChar >= 'A') || (aChar >= 'a' && aChar <= 'z') || aChar == ',')
        return true;
    return false;
}

18.求最大数字

private static void comMaxNum() {
    Scanner sc = new Scanner(System.in);
    String str = sc.nextLine();
    char[] chars = str.toCharArray();
    Map<Character, Integer> map = new HashMap<>();
    for (int i = 0; i < chars.length; i++) {
        Integer orDefault = map.getOrDefault(chars[i], 0);
        map.put(chars[i], orDefault + 1);
    }
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < chars.length; i++) {
        char cc = chars[i];
        if (judgeDel(i, map, chars)) {
            map.put(cc, map.get(cc) - 1);
        } else {
            sb.append(cc);
        }
    }
    System.out.println(sb);
}

// i对应c,到下一个c之间,如果存在比c大的数
// 1:这个数出现次数不大于2,就删了c
// 2:这个数出现次数大于2,递归判断这个数要不要删
// 34533
// 546476644
// 5445795045
static Set<Integer> sets = new HashSet<>();

private static boolean judgeDel(int i, Map<Character, Integer> map, char[] chars) {
    if (map.get(chars[i]) <= 2) return false;
    if (i == chars.length - 1) return true;
    for (int j = i + 1; j < chars.length; j++) {
        if (chars[i] < chars[j]) {
            return true;
        } else if (chars[i] == chars[j]) {
            break;
        }
    }
    return false;
}

19.不含101的数

private static void noInclude101() {
    Scanner in = new Scanner(System.in);
    int l = in.nextInt();
    int r = in.nextInt();
    int res = r - l + 1;
    while (l <= r) {
        int temp = 5;
        int jud = 7;
        while (temp <= l) {
            if ((jud & l) == temp) {
                res--;
                break;
            } else {
                temp = temp << 1;
                jud = jud << 1;
            }
        }
        l++;
    }
    System.out.println(res);
}

20.取出尽量少的球

private static void getMinBall() {
    Scanner sc = new Scanner(System.in);

    class Ball {
        int index;
        int val;
        int diff;

        Ball(int index, int val) {
            this.index = index;
            this.val = val;
            this.diff = 0;
        }
    }

    int sum = sc.nextInt();
    int len = sc.nextInt();
    Ball[] arr = new Ball[len];
    for (int i = 0; i < len; i++) {
        arr[i] = new Ball(i, sc.nextInt());
        sum -= arr[i].val;
    }

    if (sum >= 0) {
        System.out.println(" ");
    }
    // 排序
    Arrays.sort(arr, new Comparator<Ball>() {
        @Override
        public int compare(Ball o1, Ball o2) {
            return o1.val - o2.val;
        }
    });
    int index = len - 2;
    Ball leftBall = arr[index];
    while (sum < 0) {
        for (int i = len - 1; i >= index; i--) {
            Ball ball = arr[i];
            ball.diff = ball.val - leftBall.val;
            sum += ball.diff;
        }
        index--;
        leftBall = arr[index];
    }
    Arrays.sort(arr, new Comparator<Ball>() {
        @Override
        public int compare(Ball o1, Ball o2) {
            return o1.index - o2.index;
        }
    });
    for (int i = 0; i < len; i++) {
        System.out.print(" " + arr[i].diff);
    }
}

21.对称字符

public static void reverseStr() {
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    for (int i = 0; i < n; i++) {
        int a = sc.nextInt();
        long b = sc.nextLong();
        System.out.println(findReverseColor(a, b) == 1 ? "RED" : "BLUE");
    }
}

/**
 * 1 red -1 blue
 * n:第几次反转
 * k:第几个
 */
private static int findReverseColor(int n, long k) {
    if (n == 1) return 1;
    if (n == 2) {
        return k == 0 ? -1 : 1;
    }
    int len = (int) Math.pow(2, n - 1);
    if (k >= len / 2) {
        return findReverseColor(n - 1, k - len / 2);
    } else {
        return -findReverseColor(n - 1, k);
    }

}

22.分奖金

private static void salary() {
    Scanner in = new Scanner(System.in);
    int n = in.nextInt();
    int[] arr = new int[n];
    for (int i = 0; i < n; i++) {
        arr[i] = in.nextInt();
    }
    int[] res = new int[n];
    for (int i = 0; i < n; i++) {
        res[i] = arr[i];
        for (int j = i + 1; j < n; j++) {
            if (arr[j] > arr[i]) {
                res[i] = (arr[j] - res[i]) * (j - i);
                break;
            }
        }
    }
    for (int i = 0; i < n - 1; i++) {
        System.out.print(res[i] + " ");
    }
    System.out.print(res[n - 1]);
}

23.查找树中元素

public class huawei {
    // 查找树中元素
    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        int size = Integer.parseInt(in.nextLine());
        // 存储树结构
        int[][] nodes = new int[size][];

        for (int i = 0; i < size; i++) {

            nodes[i] = parseOneLine(in.nextLine());

        }
        // 要找的坐标
        int[] xy = parseOneLine(in.nextLine());
        // 执行查找
        String result = doQuery(nodes, xy[0], xy[1]);

        System.out.println(result);

    }

    private static int[] parseOneLine(String text) {

        ByteArrayInputStream stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));

        Scanner in = new Scanner(stream);

        List<Integer> list = new ArrayList<>();

        while (in.hasNext()) {

            list.add(in.nextInt());

        }

        return list.stream().mapToInt(it -> it).toArray();

    }



    private static String doQuery(int[][] nodes, int x, int y) {

        if (x < 0 || y < 0) {

            return "{}";

        }

        // Please enter you code to implement this function
        // 首先遍历,找到第x层的数据有哪些,然后找出来第y个即可
        if(x == 0) return "{" + nodes[0][0] + "}";
        x--;
        Deque<Integer> deque = new LinkedList<>();
        for(int i=1;i<nodes[0].length;i++){
            deque.addLast(nodes[0][i]);
        }
        while(x-- > 0){
            int size = deque.size();
            for (int i = 0; i < size; i++) {
                Integer index = deque.pollFirst();
                for (int j = 1; j < nodes[index].length; j++) {
                    deque.addLast(nodes[index][j]);
                }
            }
        }
        while(y-- > 0){
            deque.pollFirst();
        }
        if (deque.isEmpty()) return "{}";
        return "{" + nodes[deque.peekFirst()][0] + "}";
    }

}

24.相同数字的积木游戏

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int max = -1;
        Map<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int num = sc.nextInt();
            if(!map.containsKey(num)){
                map.put(num,i);
            }else {
                int diff = i - map.get(num);
                max = Math.max(max,diff);
            }
        }
        System.out.println(max);
    }
}

25.计算至少需要多少个快递主站点

总体时间介于超时和不超时之间,还可以优化

public class Main {
    /**
     * 4
     * 1 1 1 1
     * 1 1 1 0
     * 1 1 1 0
     * 1 0 0 1
     */
    static Set<Integer> sets = new HashSet<>();
    public static void main(String[] args) {
        // 读取数据
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[][] arr = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                arr[i][j] = sc.nextInt();
            }
        }
        // 这是一个无向图,所以随便选择一个节点开始遍历,被遍历过的节点记录在集合里
        int res = 0;
        for (int i = 0; i < n; i++) {
            if(!sets.contains(i)){
                bfs(arr,i);
                res++;
            }
        }

        System.out.println(res);
    }

    private static void bfs(int[][] arr, int i) {
        if(sets.contains(i)) return;
        sets.add(i);
        int[] indexs = arr[i];
        int n = arr.length;
        for (int j = 0; j < n; j++) {
            if(indexs[j] == 1 && !sets.contains(j)){
                bfs(arr,j);
            }
        }
    }
}

26.贪心的商人

本题需要支持多次买卖求最大,但是无论是一次买卖还是多次买卖,最后结果都是只通过80%,可能还要考虑是否每次将货物全部买卖,也可能是有20%的用例不准确

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int number = sc.nextInt();
        int days = sc.nextInt();
        int[] limit = new int[number];
        for (int i = 0; i < number; i++) {
            limit[i] = sc.nextInt();
        }
        int[][] goods = new int[number][days];
        for (int i = 0; i < number; i++) {
            for (int j = 0; j < days; j++) {
                goods[i][j] = sc.nextInt();
            }
        }

        int maxMoney = 0;
        // 因为几件商品没有关联性,因此可以分别计算每件商品的最大利润
        for (int i = 0; i < number; i++) {
            // 计算第i件商品利润
            //int money = getMoney2(limit[i], goods[i]);
            int money = getMoney(limit[i], goods[i]);
            maxMoney += money;
        }
        System.out.println(maxMoney);
    }

    // 当前是一次买卖,实际上本题不限制买卖次数
    private static int getMoney2(int maxVolume, int[] moneyArr) {
        // 依次遍历每天金额,在当天,只有两种状态,买入了和没买入
        int len = moneyArr.length;
        // dp[i][0]表示第i天不持有商品的最大利润
        // dp[i][1]表示第i天持有商品的最大利润
        int[][] dp = new int[len][2];
        dp[0][0] = 0;
        dp[0][1] = -moneyArr[0] * maxVolume;
        for (int i = 1; i < len; i++) {
            dp[i][0] = Math.max(dp[i - 1][1] + moneyArr[i] * maxVolume, dp[i - 1][0]);
            dp[i][1] = Math.max(dp[i - 1][0] - moneyArr[i] * maxVolume, dp[i - 1][1]);
        }
        return Math.max(0, dp[len - 1][0]);
    }

    // 优化版本,支持多次买卖---依然80通过率
    private static int getMoney(int maxVolume, int[] moneyArr) {
        int len = moneyArr.length;
        //首先是交易次数,最多为 days/2
        int maxBuySell = len / 2;
        // 统计手上货物哪天买入,
        int[][] buy = new int[len][maxBuySell + 1];
        // 统计手上货物哪天卖出
        int[][] sell = new int[len][maxBuySell + 1];
        // 初始化
        buy[0][0] = -maxVolume * moneyArr[0];
        sell[0][0] = 0;
        // 初始化边界条件
        for (int i = 1; i <= maxBuySell; i++) {
            buy[0][i] = Integer.MIN_VALUE / 2;
            sell[0][i] = Integer.MIN_VALUE / 2;
        }

        for (int i = 1; i < len; i++) {
            int price = maxVolume * moneyArr[i];
            buy[i][0] = Math.max(buy[i - 1][0], sell[i - 1][0] - price);
            for (int j = 1; j <= maxBuySell; j++) {
                buy[i][j] = Math.max(buy[i - 1][j], sell[i - 1][j] - price);
                sell[i][j] = Math.max(sell[i - 1][j], buy[i - 1][j - 1] + price);
            }
        }

        int res = 0;
        for (int i = 0; i <= maxBuySell; i++) {
            res = Math.max(sell[len - 1][i], res);
        }
        return res;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值