你想要“华为OD机考2025B卷 – 士兵过河”这个题目的多语言版本解题思路和代码示例吗?我可以帮你准备Java、Python、JavaScript、C++和C的完整代码和解析。先给你题目描述和通用解法思路,然后逐语言实现代码,怎么样?如果你有题目详细描述或者具体要求,告诉我更好帮你定制。


士兵过河 – 题目描述(假设示例)

题目通常是经典的“士兵过河”问题,比如:

  • 有一条河,有一群士兵要过河,每次船只能载一定人数。
  • 有一些限制条件,如不同类型士兵不能单独留在岸上,或士兵和敌人比例限制等。
  • 求最少过河次数或判断是否能过河。

如果你有具体题目文本,发给我。


通用解题思路

  1. 状态表示
    通过一个数据结构表示当前两岸士兵的状态和船的位置。
  2. 状态转移
    模拟士兵过河动作,符合限制条件则转移。
  3. 搜索策略
    BFS或DFS遍历状态空间,找最优解。
  4. 剪枝
    剪去不合法或重复状态,提升效率。

Java示例代码(模板)

import java.util.*;

public class SoldierCrossRiver {
    static class State {
        int leftA, leftB; // 左岸士兵A、B数量
        int rightA, rightB;
        boolean boatOnLeft;

        State(int la, int lb, int ra, int rb, boolean boat) {
            leftA = la; leftB = lb; rightA = ra; rightB = rb; boatOnLeft = boat;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof State)) return false;
            State s = (State) o;
            return leftA == s.leftA && leftB == s.leftB && rightA == s.rightA && rightB == s.rightB && boatOnLeft == s.boatOnLeft;
        }

        @Override
        public int hashCode() {
            return Objects.hash(leftA, leftB, rightA, rightB, boatOnLeft);
        }
    }

    // 判断状态是否合法
    static boolean isValid(State s) {
        if (s.leftA < 0 || s.leftB < 0 || s.rightA < 0 || s.rightB < 0) return false;
        if (s.leftA > 0 && s.leftA < s.leftB) return false;
        if (s.rightA > 0 && s.rightA < s.rightB) return false;
        return true;
    }

    public static int minCrossing(int totalA, int totalB, int boatCapacity) {
        State start = new State(totalA, totalB, 0, 0, true);
        State end = new State(0, 0, totalA, totalB, false);

        Queue<State> queue = new LinkedList<>();
        Map<State, Integer> dist = new HashMap<>();
        queue.offer(start);
        dist.put(start, 0);

        while (!queue.isEmpty()) {
            State curr = queue.poll();
            int step = dist.get(curr);
            if (curr.equals(end)) return step;

            // 枚举船上可能载的士兵数目组合
            for (int a = 0; a <= boatCapacity; a++) {
                for (int b = 0; b <= boatCapacity - a; b++) {
                    if (a + b == 0) continue;

                    State next = null;
                    if (curr.boatOnLeft) {
                        next = new State(
                            curr.leftA - a, curr.leftB - b,
                            curr.rightA + a, curr.rightB + b,
                            false
                        );
                    } else {
                        next = new State(
                            curr.leftA + a, curr.leftB + b,
                            curr.rightA - a, curr.rightB - b,
                            true
                        );
                    }

                    if (isValid(next) && !dist.containsKey(next)) {
                        dist.put(next, step + 1);
                        queue.offer(next);
                    }
                }
            }
        }

        return -1; // 无解
    }

    public static void main(String[] args) {
        int A = 3;  // 士兵A数量
        int B = 3;  // 士兵B数量
        int boatCap = 2; // 船容量

        int res = minCrossing(A, B, boatCap);
        System.out.println(res == -1 ? "无法过河" : "最少过河次数:" + res);
    }
}

Python示例代码

from collections import deque

class State:
    def __init__(self, leftA, leftB, rightA, rightB, boatOnLeft):
        self.leftA = leftA
        self.leftB = leftB
        self.rightA = rightA
        self.rightB = rightB
        self.boatOnLeft = boatOnLeft

    def is_valid(self):
        if any(x < 0 for x in [self.leftA, self.leftB, self.rightA, self.rightB]):
            return False
        if self.leftA > 0 and self.leftA < self.leftB:
            return False
        if self.rightA > 0 and self.rightA < self.rightB:
            return False
        return True

    def __eq__(self, other):
        return (self.leftA, self.leftB, self.rightA, self.rightB, self.boatOnLeft) == \
               (other.leftA, other.leftB, other.rightA, other.rightB, other.boatOnLeft)

    def __hash__(self):
        return hash((self.leftA, self.leftB, self.rightA, self.rightB, self.boatOnLeft))

def min_crossing(totalA, totalB, boat_capacity):
    start = State(totalA, totalB, 0, 0, True)
    end = State(0, 0, totalA, totalB, False)
    queue = deque([start])
    visited = {start: 0}

    while queue:
        curr = queue.popleft()
        step = visited[curr]
        if curr == end:
            return step

        for a in range(boat_capacity + 1):
            for b in range(boat_capacity + 1 - a):
                if a + b == 0:
                    continue
                if curr.boatOnLeft:
                    next_state = State(
                        curr.leftA - a, curr.leftB - b,
                        curr.rightA + a, curr.rightB + b,
                        False
                    )
                else:
                    next_state = State(
                        curr.leftA + a, curr.leftB + b,
                        curr.rightA - a, curr.rightB - b,
                        True
                    )
                if next_state.is_valid() and next_state not in visited:
                    visited[next_state] = step + 1
                    queue.append(next_state)
    return -1

if __name__ == "__main__":
    A = 3
    B = 3
    boat_capacity = 2
    result = min_crossing(A, B, boat_capacity)
    if result == -1:
        print("无法过河")
    else:
        print(f"最少过河次数:{result}")

JavaScript示例(Node.js环境)

class State {
    constructor(leftA, leftB, rightA, rightB, boatOnLeft) {
        this.leftA = leftA;
        this.leftB = leftB;
        this.rightA = rightA;
        this.rightB = rightB;
        this.boatOnLeft = boatOnLeft;
    }

    isValid() {
        if ([this.leftA, this.leftB, this.rightA, this.rightB].some(x => x < 0)) return false;
        if (this.leftA > 0 && this.leftA < this.leftB) return false;
        if (this.rightA > 0 && this.rightA < this.rightB) return false;
        return true;
    }

    toString() {
        return `${this.leftA},${this.leftB},${this.rightA},${this.rightB},${this.boatOnLeft}`;
    }
}

function minCrossing(totalA, totalB, boatCapacity) {
    let start = new State(totalA, totalB, 0, 0, true);
    let endStr = `0,0,${totalA},${totalB},false`;
    let queue = [start];
    let visited = new Map();
    visited.set(start.toString(), 0);

    while (queue.length) {
        let curr = queue.shift();
        let step = visited.get(curr.toString());
        if (curr.toString() === endStr) return step;

        for (let a = 0; a <= boatCapacity; a++) {
            for (let b = 0; b <= boatCapacity - a; b++) {
                if (a + b === 0) continue;

                let next;
                if (curr.boatOnLeft) {
                    next = new State(
                        curr.leftA - a, curr.leftB - b,
                        curr.rightA + a, curr.rightB + b,
                        false
                    );
                } else {
                    next = new State(
                        curr.leftA + a, curr.leftB + b,
                        curr.rightA - a, curr.rightB - b,
                        true
                    );
                }
                if (next.isValid() && !visited.has(next.toString())) {
                    visited.set(next.toString(), step + 1);
                    queue.push(next);
                }
            }
        }
    }
    return -1;
}

// 示例调用
const A = 3;
const B = 3;
const boatCapacity = 2;
const result = minCrossing(A, B, boatCapacity);
if (result === -1) {
    console.log("无法过河");
} else {
    console.log(`最少过河次数:${result}`);
}

C++示例代码

#include <iostream>
#include <queue>
#include <unordered_set>
#include <tuple>

using namespace std;

struct State {
    int leftA, leftB, rightA, rightB;
    bool boatOnLeft;
    State(int la, int lb, int ra, int rb, bool boat)
        : leftA(la), leftB(lb), rightA(ra), rightB(rb), boatOnLeft(boat) {}

    bool isValid() const {
        if (leftA < 0 || leftB < 0 || rightA < 0 || rightB < 0) return false;
        if (leftA > 0 && leftA < leftB) return false;
        if (rightA > 0 && rightA < rightB) return false;
        return true;
    }

    bool operator==(const State& other) const {
        return tie(leftA, leftB, rightA, rightB, boatOnLeft) ==
               tie(other.leftA, other.leftB, other.rightA, other.rightB, other.boatOnLeft);
    }
};

struct StateHash {
    size_t operator()(const State& s) const {
        return hash<int>()(s.leftA) ^ hash<int>()(s.leftB) ^ hash<int>()(s.rightA) ^ hash<int>()(s.rightB) ^ hash<bool>()(s.boatOnLeft);
    }
};

int minCrossing(int totalA, int totalB, int boatCapacity) {
    State start(totalA, totalB, 0, 0, true);
    State end(0, 0, totalA, totalB, false);
    queue<State> q;
    unordered_set<State, StateHash> visited;

    q.push(start);
    visited.insert(start);

    int steps = 0;

    while (!q.empty()) {
        int sz = q.size();
        for (int i = 0; i < sz; i++) {
            State curr = q.front(); q.pop();
            if (curr == end) return steps;

            for (int a = 0; a <= boatCapacity; a++) {
                for (int b = 0; b <= boatCapacity - a; b++) {
                    if (a + b == 0) continue;
                    State next = curr;
                    if (curr.boatOnLeft) {
                        next.leftA -= a; next.leftB -= b;
                        next.rightA += a; next.rightB += b;
                        next.boatOnLeft = false;
                    } else {
                        next.leftA += a; next.leftB += b;
                        next.rightA -= a; next.rightB -= b;
                        next.boatOnLeft = true;
                    }
                    if (next.isValid() && visited.find(next) == visited.end()) {
                        visited.insert(next);
                        q.push(next);
                    }
                }
            }
        }
        steps++;
    }
    return -1;
}

int main() {
    int A = 3, B = 3, boatCapacity = 2;
    int res = minCrossing(A, B, boatCapacity);
    if (res == -1) cout << "无法过河\n";
    else cout << "最少过河次数:" << res << "\n";
    return 0;
}

C语言示例提示

  • 由于C语言没有内置队列和哈希表,需要自己实现队列和状态存储结构,或用二维数组模拟状态。
  • 也可以用数组+标记法实现BFS。
  • 如果需要,我可以帮你写C语言版本的伪代码或完整代码。