2026华为OD机试真题10.21 新系统 - 货运装载顺序校验

货运装载顺序校验(JAVA/Py/C/C++/Js/Go)题解

华为OD机试真题 新系统 华为OD上机考试真题新系统 10月21号 200分题型

华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解

题目内容

某物流分拣中心每天接收大量货运订单,每条订单带有一个「优先级」编号(编号越小,优先级越高,越应优先装载)。订单按到达系统的时间先后排成队列,因上游调度延迟,到达顺序与优先级顺序经常不一致。

分拣中心定义了一种「装载逆序」:对于队列中到达在前的订单 i i i 与到达在后的订单 j j j(即 i < j i < j i<j),若订单 i i i 的优先级编号严格大于 订单 j j j,则这两个订单构成一个装载逆序。

现给定装载优先级数组 priorities,其中 priorities[i] 表示第 i i i 个到达的订单的优先级编号,请返回装载逆序的总数。数组元素可能重复,重复值之间不构成逆序。

输入描述

输入只有一行,形如:

复制代码
p0,p1,...,p(n-1)

元素之间用半角逗号分隔。

取值范围:

  1. 1 ≤ n ≤ 50000 1 \le n \le 50000 1≤n≤50000,其中 n n n 为 priorities 的长度;
  2. 0 ≤ priorities i ≤ 10 5 0 \le \text{priorities}i \le 10^5 0≤prioritiesi≤105;
  3. 数组元素可能存在重复值;只有严格大于才构成装载逆序。

输出描述

输出一行一个十进制整数,表示装载逆序的总数。

数据保证答案不超过 50000 × 49999 / 2 = 1249975000 50000 \times 49999 / 2 = 1249975000 50000×49999/2=1249975000;标程仍统一使用 64 位整数累加,留足余量。

样例1

输入

复制代码
5,3,2,4,1

输出

复制代码
8

说明

  • 构成的装载逆序对为: ( 5 , 3 ) (5,3) (5,3)、 ( 5 , 2 ) (5,2) (5,2)、 ( 5 , 4 ) (5,4) (5,4)、 ( 5 , 1 ) (5,1) (5,1)、 ( 3 , 2 ) (3,2) (3,2)、 ( 3 , 1 ) (3,1) (3,1)、 ( 2 , 1 ) (2,1) (2,1)、 ( 4 , 1 ) (4,1) (4,1),共 8 8 8 对。
  • 队列中优先级编号最大( 5 5 5)的订单排在最前,与后面所有订单都构成逆序;编号 1 1 1 排在最后,与前面所有比它大的订单都构成逆序。

样例2

输入

复制代码
1,2,3,4,5

输出

复制代码
0

说明

  • 队列已按优先级编号升序排列(编号从小到大),每个订单都排在应处的位置。
  • 不存在「先到达但优先级更低」的错位,装载逆序数为 0 0 0。

样例3

输入

复制代码
3,1,2

输出

复制代码
2

说明

  • 逐对检查: 3 > 1 3 > 1 3>1 构成逆序, 3 > 2 3 > 2 3>2 构成逆序, 1 < 2 1 < 2 1<2 不构成逆序。
  • 编号 3 3 3 排在首位却优先级最低,与后两个订单均构成逆序; 1 1 1 和 2 2 2 的相对顺序正确,不构成逆序;共 2 2 2 对。

解题思路

思路:树状数组

  1. 题目给出的优先级范围为0-100000,因此可以使用树状数组进行求解。树状数组有两个核心方法,简单说说

    1. query(x): 查询[1,x]的前缀和值
    2. update(x): 更新[x,maxN]的前缀和值
  2. 从左往右遍历数组,使用树状数组维护已经出现过的优先级数量,对于当前元素p[i]

    1. 查询已经出现、优先级小于等于当前值的元素数量num。
    2. 用已经遍历的元素减去num,就得到之前比当前元素大的数量,就是当前元素产生的逆序对数量。
    3. 将当前元素加入树状数组。
  3. 按照上述逻辑即可求出对应逆序对数量。

C++

cpp 复制代码
#include <bits/stdc++.h>
#include <vector>
using namespace std;
using ll = long long;
// 根据p范围决定
const int MAXV = 100001;

// 通用 切割函数 函数 将字符串str根据delimiter进行切割
vector<int> split(const string& str, const string& delimiter) {
    vector<int> result;
    size_t start = 0;
    size_t end = str.find(delimiter);
    while (end != string::npos) {
        result.push_back(stoi(str.substr(start, end - start)));
        start = end + delimiter.length();
        end = str.find(delimiter, start);
    }
    // 添加最后一个部分
    result.push_back(stoi(str.substr(start)));
    return result;
}

int lowbit(int x) {
    return x & -x;
}

// 树状数组查询
int query (int x, vector<int>& tree) {
        int sum = 0;
        while (x > 0) {
            sum += tree[x];
            x -= lowbit(x);
        }
        return sum;
}
// 更新
void update(int x, vector<int>& tree) {
    while (x <= MAXV) {
        tree[x]++;
        x += lowbit(x);
    }
}


ll solve(vector<int>& p) {
    int n = p.size();
    vector<int> tree(MAXV + 1, 0);
    long long ans = 0;
    for (int i = 0; i < p.size(); i++) {
        // 将优先级映射到树状数组下标,避免下标为0
        int x = p[i] + 1;

        // 已遍历元素中,严格大于当前值的数量
        ans += i - query(x, tree);
        
        update(x, tree);
    }
    return ans;
}


int main() {
    string input;
    getline(cin, input);
    vector<int> p = split(input, ",");
    cout << solve(p);
    return 0;
}

JAVA

java 复制代码
import java.util.*;

public class Main {

    // 根据p范围决定
    static final int MAXV = 100001;

    // lowbit
    static int lowbit(int x) {
        return x & -x;
    }

    // 树状数组查询
    static int query(int x, int[] tree) {
        int sum = 0;
        while (x > 0) {
            sum += tree[x];
            x -= lowbit(x);
        }
        return sum;
    }

    // 更新
    static void update(int x, int[] tree) {
        while (x <= MAXV) {
            tree[x]++;
            x += lowbit(x);
        }
    }

    static long solve(int[] p) {
        int n = p.length;
        int[] tree = new int[MAXV + 1];
        long ans = 0;

        for (int i = 0; i < n; i++) {
            // 将优先级映射到树状数组下标,避免下标为0
            int x = p[i] + 1;

            // 已遍历元素中,严格大于当前值的数量
            ans += i - query(x, tree);

            update(x, tree);
        }

        return ans;
    }

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

        String input = sc.nextLine();
        String[] tokens = input.split(",");

        int[] p = new int[tokens.length];
        for (int i = 0; i < tokens.length; i++) {
            p[i] = Integer.parseInt(tokens[i]);
        }

        System.out.println(solve(p));
    }
}

Python

python 复制代码
# 根据p范围决定
MAXV = 100001


def lowbit(x):
    return x & -x


# 树状数组查询
def query(x, tree):
    sum_val = 0
    while x > 0:
        sum_val += tree[x]
        x -= lowbit(x)
    return sum_val


# 更新
def update(x, tree):
    while x <= MAXV:
        tree[x] += 1
        x += lowbit(x)


def solve(p):
    n = len(p)
    tree = [0] * (MAXV + 1)
    ans = 0

    for i in range(n):
        # 将优先级映射到树状数组下标,避免下标为0
        x = p[i] + 1

        # 已遍历元素中,严格大于当前值的数量
        ans += i - query(x, tree)

        update(x, tree)

    return ans


if __name__ == "__main__":
    input_str = input().strip()
    p = list(map(int, input_str.split(",")))

    print(solve(p))

JavaScript

js 复制代码
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

// 根据p范围决定
const MAXV = 100001;

// lowbit
function lowbit(x) {
    return x & -x;
}

// 树状数组查询
function query(x, tree) {
    let sum = 0;
    while (x > 0) {
        sum += tree[x];
        x -= lowbit(x);
    }
    return sum;
}

// 更新
function update(x, tree) {
    while (x <= MAXV) {
        tree[x]++;
        x += lowbit(x);
    }
}

function solve(p) {
    const n = p.length;
    const tree = new Int32Array(MAXV + 1);
    let ans = 0;

    for (let i = 0; i < n; i++) {
        // 将优先级映射到树状数组下标,避免下标为0
        const x = p[i] + 1;

        // 已遍历元素中,严格大于当前值的数量
        ans += i - query(x, tree);

        update(x, tree);
    }

    return ans;
}

rl.on("line", (input) => {
    const p = input.trim().split(",").map(Number);

    console.log(solve(p));
    rl.close();
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// 根据p范围决定
const MAXV = 100001

// lowbit
func lowbit(x int) int {
	return x & -x
}

// 树状数组查询
func query(x int, tree []int) int {
	sum := 0
	for x > 0 {
		sum += tree[x]
		x -= lowbit(x)
	}
	return sum
}

// 更新
func update(x int, tree []int) {
	for x <= MAXV {
		tree[x]++
		x += lowbit(x)
	}
}

func solve(p []int) int64 {
	n := len(p)
	tree := make([]int, MAXV+1)
	var ans int64 = 0

	for i := 0; i < n; i++ {
		// 将优先级映射到树状数组下标,避免下标为0
		x := p[i] + 1

		// 已遍历元素中,严格大于当前值的数量
		ans += int64(i - query(x, tree))

		update(x, tree)
	}

	return ans
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	input, _ := reader.ReadString('\n')
	input = strings.TrimSpace(input)

	tokens := strings.Split(input, ",")
	p := make([]int, len(tokens))

	for i, token := range tokens {
		p[i], _ = strconv.Atoi(token)
	}

	fmt.Println(solve(p))
}

C语言

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 根据p范围决定
#define MAXV 100001

// lowbit
int lowbit(int x) {
    return x & -x;
}

// 树状数组查询
int query(int x, int tree[]) {
    int sum = 0;
    while (x > 0) {
        sum += tree[x];
        x -= lowbit(x);
    }
    return sum;
}

// 更新
void update(int x, int tree[]) {
    while (x <= MAXV) {
        tree[x]++;
        x += lowbit(x);
    }
}

long long solve(int p[], int n) {
    int tree[MAXV + 1] = {0};
    long long ans = 0;

    for (int i = 0; i < n; i++) {
        // 将优先级映射到树状数组下标,避免下标为0
        int x = p[i] + 1;

        // 已遍历元素中,严格大于当前值的数量
        ans += i - query(x, tree);

        update(x, tree);
    }

    return ans;
}

int main() {
    char input[2000005];
    fgets(input, sizeof(input), stdin);

    int p[200005];
    int n = 0;

    // 切割字符串
    char* token = strtok(input, ",\r\n");
    while (token != NULL) {
        p[n++] = atoi(token);
        token = strtok(NULL, ",\r\n");
    }

    printf("%lld\n", solve(p, n));

    return 0;
}

​

相关推荐
无限码力2 天前
2026华为OD机试真题 11月8日 新系统 【HTTP 访问日志峰值请求数】
华为od·华为od机考·华为od机试·华为od机试新系统真题·华为od最新机试真题·华为od机试11月8号真题
无限码力9 天前
2026华为OD机试真题 10月25日 新系统 【乘车顺序】
华为od·华为od机考·华为od机试真题·华为od机试·华为od机试新系统真题·华为最新机试真题
每天进步一点点km12 天前
自用-牛客网-华为机试编程模拟题1-python
华为od·华为·面试
无限码力1 个月前
华为OD面试手撕真题 【合并相邻且相等的元素】多语言题解
华为od·面试·华为od面试真题·华为od面试手撕真题·华为od面试算法真题
无限码力1 个月前
2026.9.20 华为OD机试真题 新系统 【简单 URL 路径提取器】
华为od·华为od机考·华为od机试·华为od机试真题新系统·华为od最新笔试真题题解·华为od9月20号机试真题题解
无限码力1 个月前
2026华为OD机试真题 新系统 9月27日【坚果巧克力】
算法·华为od·华为od机考·华为od机试真题·华为od机试·华为od机考真题题解·华为社招笔试真题
无限码力2 个月前
9.16华为OD机试真题 新系统 - 矩阵螺旋遍历 (Java/Py/C/C++/Js/Go)
华为od机考·华为od机试·华为od机试真题题解·华为od笔试·华为od机试真题 新系统·华为od9月16号真题
c++开发工程师2 个月前
Scrum 核心角色与分工
华为od·scrum
无限码力2 个月前
华为OD机试真题 新系统【图的遍历】
华为od·华为od机试·华为od上机考试真题·华为od机考真题·华为od机试真题题解·华为od机考真题题解·华为机试题库