2025.04.16华为暑期实习真题【寻找最便宜的地铁换乘方案】Java/Python/C++/JS/C 实现

目录

题目

思路

Code


题目

已知 A 市运营了 N 条地铁线路,市民在乘坐地铁时单条线路通票2元,换乘一次加1元。给出 N 条线路的所有站名列表,请帮乘客寻找从出发站到目的站最便官的地铁换乘方案,并输出票价。每条地铁线路不包含环路,即没有相同站名。
输入描述
第一行为地铁线路个数 N ,范围是[1,1000];
第二行到 N +1行:每条线路依次包含的站名,每个站名包含的字符个数不超过100,站点个数也不超过100,依次用空格隔开,不同线路中相同的站点名表示是一个换乘站;
第 N +2行,出发站和目的站,用空格隔开。
输入保证:若可达则为唯一解。
输出描述
第一行按照出发站﹣换乘站(可以是多个)﹣目的站的格式输出换乘方案的字符串;
第二行输出换乘方案的总票价。
如果没有任何方案可实现出发站到目的站,只输出一行: NA 。

样例1
输入

3
A B C D F
C E G H
B G I J
A J
输出

A-B-J
3
说明

从出发站A到目的站J有两个方案:一号线到C站后换乘二号线,到G站后换乘三号线到J站,换乘两次,总票价4元;
一号线到B站后换乘三号线到J站,换乘一次,总票价3元。因此按照第二个方案愉出。

样例2
输入

3
A B C D F
E G H
G I J
A J
输出

NA
说明
从出发站 A所在的一号线没有任何一个换乘站可以到二号线和三号线,因此没有方案抵达目的站J ,输出NA。

思路

典型的带有换乘的图搜索问题

1. 构图思路

  • 每个“站点”是一个图中的节点。

  • 如果两个站点在同一条线路上相邻,则它们之间连一条边,表示可以直达,不换乘。

  • 如果一个站点在多条线路中都存在,它就是“换乘点”,可以从一个线路跳转到另一个线路。

2. 图搜索方法

  • 使用 BFS(广度优先搜索)进行最短路径搜索,记录路径以及换乘次数。

  • BFS 队列中记录:

    • 当前站名

    • 当前线路编号

    • 当前路径

    • 换乘次数

3. 特别注意

  • 要避免重复访问相同站点+线路组合。

  • 票价 = 2(第一条线) + 1 × 换乘次数。

Python

from collections import defaultdict, deque

def find_best_route():
    import sys
    input = sys.stdin.read
    data = input().split('\n')

    # 读取地铁线路数量
    N = int(data[0].strip())
    line_station_map = []
    station_to_lines = defaultdict(list)
    graph = defaultdict(list)

    # 构建线路信息
    for idx in range(1, N + 1):
        line = data[idx].strip().split()
        line_station_map.append(line)
        for i in range(len(line)):
            station_to_lines[line[i]].append(idx - 1)
            if i > 0:
                graph[line[i]].append(line[i - 1])
                graph[line[i - 1]].append(line[i])

    # 出发站和终点站
    start, end = data[N + 1].strip().split()

    if start == end:
        print(start)
        print(2)
        return

    # BFS队列:当前站点, 当前路径, 当前线路编号, 当前换乘次数
    queue = deque()
    visited = set()

    # 初始化起点,可能属于多个线路
    for line_id in station_to_lines[start]:
        queue.append((start, [start], line_id, 0))
        visited.add((start, line_id))

    final_path = []
    min_transfer = float('inf')

    while queue:
        curr, path, curr_line, transfer = queue.popleft()

        if curr == end:
            if transfer < min_transfer:
                final_path = path
                min_transfer = transfer
            continue

        for neighbor in graph[curr]:
            common_lines = set(station_to_lines[curr]) & set(station_to_lines[neighbor])
            for next_line in common_lines:
                is_transfer = (next_line != curr_line)
                new_transfer = transfer + 1 if is_transfer else transfer
                if (neighbor, next_line) not in visited:
                    visited.add((neighbor, next_line))
                    queue.append((neighbor, path + [neighbor], next_line, new_transfer))

    # 没有路径
    if not final_path:
        print("NA")
        return

    # 路径优化:只输出换乘节点和终点
    simplified_path = [final_path[0]]
    prev_line = None

    for i in range(1, len(final_path)):
        prev = final_path[i - 1]
        curr = final_path[i]
        common = set(station_to_lines[prev]) & set(station_to_lines[curr])

        if not common:
            simplified_path.append(prev)
            prev_line = None
        elif prev_line is None:
            prev_line = list(common)[0]
        elif prev_line not in station_to_lines[curr]:
            simplified_path.append(prev)
            prev_line = list(common)[0]

    # 加入终点
    if simplified_path[-1] != end:
        simplified_path.append(end)

    # 重新计算换乘次数
    transfer_count = 0
    prev = simplified_path[0]
    prev_line = None

    for i in range(1, len(simplified_path)):
        curr = simplified_path[i]
        common_lines = set(station_to_lines[prev]) & set(station_to_lines[curr])
        if not common_lines:
            transfer_count += 1
            prev_line = None
        elif prev_line is None:
            prev_line = list(common_lines)[0]
        elif prev_line not in station_to_lines[curr]:
            transfer_count += 1
            prev_line = list(common_lines)[0]
        prev = curr

    # 输出路径和票价
    print("-".join(simplified_path))
    print(2 + transfer_count)
find_best_route()

 Java

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        List<List<String>> lineStationMap = new ArrayList<>();
        Map<String, List<Integer>> stationToLines = new HashMap<>();
        Map<String, List<String>> graph = new HashMap<>();

        // 构建线路信息
        for (int idx = 0; idx < N; idx++) {
            String[] line = br.readLine().trim().split(" ");
            lineStationMap.add(Arrays.asList(line));
            for (int i = 0; i < line.length; i++) {
                stationToLines.computeIfAbsent(line[i], k -> new ArrayList<>()).add(idx);
                if (i > 0) {
                    graph.computeIfAbsent(line[i], k -> new ArrayList<>()).add(line[i-1]);
                    graph.computeIfAbsent(line[i-1], k -> new ArrayList<>()).add(line[i]);
                }
            }
        }

        String[] startEnd = br.readLine().trim().split(" ");
        String start = startEnd[0];
        String end = startEnd[1];

        if (start.equals(end)) {
            System.out.println(start);
            System.out.println(2);
            return;
        }

        // BFS队列:当前站点, 当前路径, 当前线路编号, 当前换乘次数
        Queue<State> queue = new LinkedList<>();
        Set<Pair> visited = new HashSet<>();

        // 初始化起点,可能属于多个线路
        for (int lineId : stationToLines.getOrDefault(start, new ArrayList<>())) {
            List<String> initialPath = new ArrayList<>();
            initialPath.add(start);
            queue.add(new State(start, initialPath, lineId, 0));
            visited.add(new Pair(start, lineId));
        }

        List<String> finalPath = new ArrayList<>();
        int minTransfer = Integer.MAX_VALUE;

        while (!queue.isEmpty()) {
            State current = queue.poll();

            if (current.station.equals(end)) {
                if (current.transfer < minTransfer) {
                    finalPath = current.path;
                    minTransfer = current.transfer;
                }
                continue;
            }

            for (String neighbor : graph.getOrDefault(current.station, new ArrayList<>())) {
                Set<Integer> commonLines = new HashSet<>(stationToLines.getOrDefault(current.station, new ArrayList<>()));
                commonLines.retainAll(new HashSet<>(stationToLines.getOrDefault(neighbor, new ArrayList<>())));
                
                for (int nextLine : commonLines) {
                    boolean isTransfer = (nextLine != current.line);
                    int newTransfer = isTransfer ? current.transfer + 1 : current.transfer;
                    Pair key = new Pair(neighbor, nextLine);
                    
                    if (!visited.contains(key)) {
                        visited.add(key);
                        List<String> newPath = new ArrayList<>(current.path);
                        newPath.add(neighbor);
                        queue.add(new State(neighbor, newPath, nextLine, newTransfer));
                    }
                }
            }
        }

        // 没有路径
        if (finalPath.isEmpty()) {
            System.out.println("NA");
            return;
        }

        // 路径优化:只输出换乘节点和终点
        List<String> simplifiedPath = new ArrayList<>();
        simplifiedPath.add(finalPath.get(0));
        Integer prevLine = null;

        for (int i = 1; i < finalPath.size(); i++) {
            String prev = finalPath.get(i-1);
            String curr = finalPath.get(i);
            Set<Integer> commonLines = new HashSet<>(stationToLines.getOrDefault(prev, new ArrayList<>()));
            commonLines.retainAll(new HashSet<>(stationToLines.getOrDefault(curr, new ArrayList<>())));

            if (commonLines.isEmpty()) {
                simplifiedPath.add(prev);
                prevLine = null;
            } else if (prevLine == null) {
                prevLine = commonLines.iterator().next();
            } else if (!commonLines.contains(prevLine)) {
                simplifiedPath.add(prev);
                prevLine = commonLines.iterator().next();
            }
        }

        // 加入终点
        if (!simplifiedPath.get(simplifiedPath.size()-1).equals(end)) {
            simplifiedPath.add(end);
        }

        // 重新计算换乘次数
        int transferCount = 0;
        String prev = simplifiedPath.get(0);
        prevLine = null;

        for (int i = 1; i < simplifiedPath.size(); i++) {
            String curr = simplifiedPath.get(i);
            Set<Integer> commonLines = new HashSet<>(stationToLines.getOrDefault(prev, new ArrayList<>()));
            commonLines.retainAll(new HashSet<>(stationToLines.getOrDefault(curr, new ArrayList<>())));
            
            if (commonLines.isEmpty()) {
                transferCount++;
                prevLine = null;
            } else if (prevLine == null) {
                prevLine = commonLines.iterator().next();
            } else if (!commonLines.contains(prevLine)) {
                transferCount++;
                prevLine = commonLines.iterator().next();
            }
            prev = curr;
        }

        // 输出路径和票价
        System.out.println(String.join("-", simplifiedPath));
        System.out.println(2 + transferCount);
    }

    static class State {
        String station;
        List<String> path;
        int line;
        int transfer;

        State(String station, List<String> path, int line, int transfer) {
            this.station = station;
            this.path = path;
            this.line = line;
            this.transfer = transfer;
        }
    }

    static class Pair {
        String station;
        int line;

        Pair(String station, int line) {
            this.station = station;
            this.line = line;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pair pair = (Pair) o;
            return line == pair.line && station.equals(pair.station);
        }

        @Override
        public int hashCode() {
            return Objects.hash(station, line);
        }
    }
}

 C++

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <sstream>
#include <algorithm>
#include <climits>

using namespace std;

void find_best_route() {
    int N;
    cin >> N;
    cin.ignore(); // 消耗换行符
    
    vector<vector<string>> line_station_map;
    unordered_map<string, vector<int>> station_to_lines;
    unordered_map<string, vector<string>> graph;
    
    // 构建线路信息
    for (int idx = 0; idx < N; idx++) {
        string line;
        getline(cin, line);
        istringstream iss(line);
        vector<string> stations;
        string station;
        
        while (iss >> station) {
            stations.push_back(station);
            station_to_lines[station].push_back(idx);
            if (!stations.empty()) {
                graph[station].push_back(stations.back());
                if (stations.size() > 1) {
                    graph[stations[stations.size()-2]].push_back(station);
                }
            }
        }
        line_station_map.push_back(stations);
    }
    
    string start, end;
    cin >> start >> end;
    
    if (start == end) {
        cout << start << endl;
        cout << 2 << endl;
        return;
    }
    
    // BFS队列:当前站点, 当前路径, 当前线路编号, 当前换乘次数
    struct State {
        string station;
        vector<string> path;
        int line;
        int transfer;
    };
    
    queue<State> q;
    unordered_set<string> visited;
    
    // 初始化起点,可能属于多个线路
    for (int line_id : station_to_lines[start]) {
        vector<string> initial_path = {start};
        q.push({start, initial_path, line_id, 0});
        visited.insert(start + "," + to_string(line_id));
    }
    
    vector<string> final_path;
    int min_transfer = INT_MAX;
    
    while (!q.empty()) {
        State current = q.front();
        q.pop();
        
        if (current.station == end) {
            if (current.transfer < min_transfer) {
                final_path = current.path;
                min_transfer = current.transfer;
            }
            continue;
        }
        
        for (string neighbor : graph[current.station]) {
            vector<int> curr_lines = station_to_lines[current.station];
            vector<int> neighbor_lines = station_to_lines[neighbor];
            vector<int> common_lines;
            
            sort(curr_lines.begin(), curr_lines.end());
            sort(neighbor_lines.begin(), neighbor_lines.end());
            set_intersection(curr_lines.begin(), curr_lines.end(),
                           neighbor_lines.begin(), neighbor_lines.end(),
                           back_inserter(common_lines));
            
            for (int next_line : common_lines) {
                bool is_transfer = (next_line != current.line);
                int new_transfer = is_transfer ? current.transfer + 1 : current.transfer;
                string key = neighbor + "," + to_string(next_line);
                
                if (visited.find(key) == visited.end()) {
                    visited.insert(key);
                    vector<string> new_path = current.path;
                    new_path.push_back(neighbor);
                    q.push({neighbor, new_path, next_line, new_transfer});
                }
            }
        }
    }
    
    // 没有路径
    if (final_path.empty()) {
        cout << "NA" << endl;
        return;
    }
    
    // 路径优化:只输出换乘节点和终点
    vector<string> simplified_path = {final_path[0]};
    int prev_line = -1;
    
    for (int i = 1; i < final_path.size(); i++) {
        string prev = final_path[i-1];
        string curr = final_path[i];
        vector<int> prev_lines = station_to_lines[prev];
        vector<int> curr_lines = station_to_lines[curr];
        vector<int> common_lines;
        
        sort(prev_lines.begin(), prev_lines.end());
        sort(curr_lines.begin(), curr_lines.end());
        set_intersection(prev_lines.begin(), prev_lines.end(),
                        curr_lines.begin(), curr_lines.end(),
                        back_inserter(common_lines));
        
        if (common_lines.empty()) {
            simplified_path.push_back(prev);
            prev_line = -1;
        } else if (prev_line == -1) {
            prev_line = common_lines[0];
        } else if (find(common_lines.begin(), common_lines.end(), prev_line) == common_lines.end()) {
            simplified_path.push_back(prev);
            prev_line = common_lines[0];
        }
    }
    
    // 加入终点
    if (simplified_path.back() != end) {
        simplified_path.push_back(end);
    }
    
    // 重新计算换乘次数
    int transfer_count = 0;
    string prev = simplified_path[0];
    int prev_line_count = -1;
    
    for (int i = 1; i < simplified_path.size(); i++) {
        string curr = simplified_path[i];
        vector<int> prev_lines = station_to_lines[prev];
        vector<int> curr_lines = station_to_lines[curr];
        vector<int> common_lines;
        
        sort(prev_lines.begin(), prev_lines.end());
        sort(curr_lines.begin(), curr_lines.end());
        set_intersection(prev_lines.begin(), prev_lines.end(),
                        curr_lines.begin(), curr_lines.end(),
                        back_inserter(common_lines));
        
        if (common_lines.empty()) {
            transfer_count++;
            prev_line_count = -1;
        } else if (prev_line_count == -1) {
            prev_line_count = common_lines[0];
        } else if (find(common_lines.begin(), common_lines.end(), prev_line_count) == common_lines.end()) {
            transfer_count++;
            prev_line_count = common_lines[0];
        }
        prev = curr;
    }
    
    // 输出路径和票价
    for (int i = 0; i < simplified_path.size(); i++) {
        if (i != 0) cout << "-";
        cout << simplified_path[i];
    }
    cout << endl;
    cout << 2 + transfer_count << endl;
}

int main() {
    find_best_route();
    return 0;
}

 JavaScript

const readline = require('readline');

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

    const input = [];
    for await (const line of rl) {
        input.push(line.trim());
    }

    const N = parseInt(input[0]);
    const lineStationMap = [];
    const stationToLines = new Map();
    const graph = new Map();

    // 构建线路信息
    for (let idx = 1; idx <= N; idx++) {
        const line = input[idx].split(' ');
        lineStationMap.push(line);
        for (let i = 0; i < line.length; i++) {
            if (!stationToLines.has(line[i])) {
                stationToLines.set(line[i], []);
            }
            stationToLines.get(line[i]).push(idx - 1); // 线路编号从0开始

            if (i > 0) {
                // 构建双向连接
                if (!graph.has(line[i])) {
                    graph.set(line[i], []);
                }
                graph.get(line[i]).push(line[i - 1]);

                if (!graph.has(line[i - 1])) {
                    graph.set(line[i - 1], []);
                }
                graph.get(line[i - 1]).push(line[i]);
            }
        }
    }

    // 读取起点和终点
    const [start, end] = input[N + 1].split(' ');

    if (start === end) {
        console.log(start);
        console.log(2);
        return;
    }

    // BFS队列:当前站点, 当前路径, 当前线路编号, 当前换乘次数
    const queue = [];
    const visited = new Set();

    // 初始化起点,可能属于多个线路
    const startLines = stationToLines.get(start) || [];
    for (const lineId of startLines) {
        queue.push({
            station: start,
            path: [start],
            line: lineId,
            transfer: 0
        });
        visited.add(`${start},${lineId}`);
    }

    let finalPath = [];
    let minTransfer = Infinity;

    while (queue.length > 0) {
        const current = queue.shift();

        if (current.station === end) {
            if (current.transfer < minTransfer) {
                finalPath = current.path;
                minTransfer = current.transfer;
            }
            continue;
        }

        const neighbors = graph.get(current.station) || [];
        for (const neighbor of neighbors) {
            const currentLines = stationToLines.get(current.station) || [];
            const neighborLines = stationToLines.get(neighbor) || [];
            
            // 找出共同线路
            const commonLines = currentLines.filter(line => 
                neighborLines.includes(line)
            );

            for (const nextLine of commonLines) {
                const isTransfer = nextLine !== current.line;
                const newTransfer = isTransfer ? current.transfer + 1 : current.transfer;
                const key = `${neighbor},${nextLine}`;

                if (!visited.has(key)) {
                    visited.add(key);
                    queue.push({
                        station: neighbor,
                        path: [...current.path, neighbor],
                        line: nextLine,
                        transfer: newTransfer
                    });
                }
            }
        }
    }

    // 没有路径
    if (finalPath.length === 0) {
        console.log("NA");
        return;
    }

    // 路径优化:只输出换乘节点和终点
    const simplifiedPath = [finalPath[0]];
    let prevLine = null;

    for (let i = 1; i < finalPath.length; i++) {
        const prev = finalPath[i - 1];
        const curr = finalPath[i];
        const prevLines = stationToLines.get(prev) || [];
        const currLines = stationToLines.get(curr) || [];
        
        const commonLines = prevLines.filter(line => 
            currLines.includes(line)
        );

        if (commonLines.length === 0) {
            simplifiedPath.push(prev);
            prevLine = null;
        } else if (prevLine === null) {
            prevLine = commonLines[0];
        } else if (!commonLines.includes(prevLine)) {
            simplifiedPath.push(prev);
            prevLine = commonLines[0];
        }
    }

    // 加入终点
    if (simplifiedPath[simplifiedPath.length - 1] !== end) {
        simplifiedPath.push(end);
    }

    // 重新计算换乘次数
    let transferCount = 0;
    let prev = simplifiedPath[0];
    prevLine = null;

    for (let i = 1; i < simplifiedPath.length; i++) {
        const curr = simplifiedPath[i];
        const prevLines = stationToLines.get(prev) || [];
        const currLines = stationToLines.get(curr) || [];
        
        const commonLines = prevLines.filter(line => 
            currLines.includes(line)
        );

        if (commonLines.length === 0) {
            transferCount++;
            prevLine = null;
        } else if (prevLine === null) {
            prevLine = commonLines[0];
        } else if (!commonLines.includes(prevLine)) {
            transferCount++;
            prevLine = commonLines[0];
        }
        prev = curr;
    }

    // 输出路径和票价
    console.log(simplifiedPath.join('-'));
    console.log(2 + transferCount);
}

findBestRoute();

 C语言

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#define MAX_STATIONS 1000
#define MAX_LINE_LENGTH 1000
#define MAX_NAME_LENGTH 50

typedef struct {
    char station[MAX_NAME_LENGTH];
    char path[MAX_STATIONS][MAX_NAME_LENGTH];
    int path_len;
    int line;
    int transfer;
} State;

typedef struct {
    char name[MAX_NAME_LENGTH];
    int lines[MAX_STATIONS];
    int line_count;
} StationInfo;

int main() {
    int N;
    scanf("%d", &N);
    getchar(); // 消耗换行符
    
    char lines[N][MAX_LINE_LENGTH];
    StationInfo stations[MAX_STATIONS];
    int station_count = 0;
    char graph[MAX_STATIONS][MAX_STATIONS][MAX_NAME_LENGTH];
    int graph_count[MAX_STATIONS] = {0};
    
    // 构建线路信息
    for (int idx = 0; idx < N; idx++) {
        fgets(lines[idx], MAX_LINE_LENGTH, stdin);
        lines[idx][strcspn(lines[idx], "\n")] = 0; // 移除换行符
        
        char *token = strtok(lines[idx], " ");
        char prev[MAX_NAME_LENGTH] = "";
        
        while (token != NULL) {
            // 添加到station_to_lines
            int found = 0;
            for (int i = 0; i < station_count; i++) {
                if (strcmp(stations[i].name, token) == 0) {
                    stations[i].lines[stations[i].line_count++] = idx;
                    found = 1;
                    break;
                }
            }
            if (!found) {
                strcpy(stations[station_count].name, token);
                stations[station_count].lines[0] = idx;
                stations[station_count].line_count = 1;
                station_count++;
            }
            
            // 构建图
            if (strlen(prev) > 0) {
                strcpy(graph[station_count-1][graph_count[station_count-1]++], prev);
                for (int i = 0; i < station_count; i++) {
                    if (strcmp(stations[i].name, prev) == 0) {
                        strcpy(graph[i][graph_count[i]++], token);
                        break;
                    }
                }
            }
            strcpy(prev, token);
            token = strtok(NULL, " ");
        }
    }
    
    char start[MAX_NAME_LENGTH], end[MAX_NAME_LENGTH];
    scanf("%s %s", start, end);
    
    if (strcmp(start, end) == 0) {
        printf("%s\n2\n", start);
        return 0;
    }
    
    // BFS队列
    State queue[MAX_STATIONS * MAX_STATIONS];
    int front = 0, rear = 0;
    char visited[MAX_STATIONS * MAX_STATIONS][MAX_NAME_LENGTH + 10];
    int visited_count = 0;
    
    // 初始化起点
    int start_idx = -1;
    for (int i = 0; i < station_count; i++) {
        if (strcmp(stations[i].name, start) == 0) {
            start_idx = i;
            break;
        }
    }
    
    if (start_idx == -1) {
        printf("NA\n");
        return 0;
    }
    
    for (int i = 0; i < stations[start_idx].line_count; i++) {
        State initial = {0};
        strcpy(initial.station, start);
        strcpy(initial.path[0], start);
        initial.path_len = 1;
        initial.line = stations[start_idx].lines[i];
        initial.transfer = 0;
        queue[rear++] = initial;
        
        sprintf(visited[visited_count++], "%s,%d", start, stations[start_idx].lines[i]);
    }
    
    State final_state = {0};
    int min_transfer = INT_MAX;
    
    while (front < rear) {
        State current = queue[front++];
        
        if (strcmp(current.station, end) == 0) {
            if (current.transfer < min_transfer) {
                final_state = current;
                min_transfer = current.transfer;
            }
            continue;
        }
        
        int curr_idx = -1;
        for (int i = 0; i < station_count; i++) {
            if (strcmp(stations[i].name, current.station) == 0) {
                curr_idx = i;
                break;
            }
        }
        
        if (curr_idx == -1) continue;
        
        for (int i = 0; i < graph_count[curr_idx]; i++) {
            char neighbor[MAX_NAME_LENGTH];
            strcpy(neighbor, graph[curr_idx][i]);
            
            int neighbor_idx = -1;
            for (int j = 0; j < station_count; j++) {
                if (strcmp(stations[j].name, neighbor) == 0) {
                    neighbor_idx = j;
                    break;
                }
            }
            
            if (neighbor_idx == -1) continue;
            
            // 找出共同线路
            int common_lines[MAX_STATIONS];
            int common_count = 0;
            for (int j = 0; j < stations[curr_idx].line_count; j++) {
                for (int k = 0; k < stations[neighbor_idx].line_count; k++) {
                    if (stations[curr_idx].lines[j] == stations[neighbor_idx].lines[k]) {
                        common_lines[common_count++] = stations[curr_idx].lines[j];
                        break;
                    }
                }
            }
            
            for (int j = 0; j < common_count; j++) {
                int next_line = common_lines[j];
                int is_transfer = (next_line != current.line);
                int new_transfer = is_transfer ? current.transfer + 1 : current.transfer;
                
                char key[MAX_NAME_LENGTH + 10];
                sprintf(key, "%s,%d", neighbor, next_line);
                
                int found = 0;
                for (int k = 0; k < visited_count; k++) {
                    if (strcmp(visited[k], key) == 0) {
                        found = 1;
                        break;
                    }
                }
                
                if (!found) {
                    strcpy(visited[visited_count++], key);
                    State new_state = {0};
                    strcpy(new_state.station, neighbor);
                    new_state.path_len = current.path_len;
                    for (int k = 0; k < current.path_len; k++) {
                        strcpy(new_state.path[k], current.path[k]);
                    }
                    strcpy(new_state.path[new_state.path_len++], neighbor);
                    new_state.line = next_line;
                    new_state.transfer = new_transfer;
                    queue[rear++] = new_state;
                }
            }
        }
    }
    
    if (final_state.path_len == 0) {
        printf("NA\n");
        return 0;
    }
    
    // 路径优化
    char simplified_path[MAX_STATIONS][MAX_NAME_LENGTH];
    int simplified_count = 1;
    strcpy(simplified_path[0], final_state.path[0]);
    int prev_line = -1;
    
    for (int i = 1; i < final_state.path_len; i++) {
        char prev[MAX_NAME_LENGTH], curr[MAX_NAME_LENGTH];
        strcpy(prev, final_state.path[i-1]);
        strcpy(curr, final_state.path[i]);
        
        int prev_idx = -1, curr_idx = -1;
        for (int j = 0; j < station_count; j++) {
            if (strcmp(stations[j].name, prev) == 0) prev_idx = j;
            if (strcmp(stations[j].name, curr) == 0) curr_idx = j;
            if (prev_idx != -1 && curr_idx != -1) break;
        }
        
        if (prev_idx == -1 || curr_idx == -1) continue;
        
        int common_lines[MAX_STATIONS];
        int common_count = 0;
        for (int j = 0; j < stations[prev_idx].line_count; j++) {
            for (int k = 0; k < stations[curr_idx].line_count; k++) {
                if (stations[prev_idx].lines[j] == stations[curr_idx].lines[k]) {
                    common_lines[common_count++] = stations[prev_idx].lines[j];
                    break;
                }
            }
        }
        
        if (common_count == 0) {
            strcpy(simplified_path[simplified_count++], prev);
            prev_line = -1;
        } else if (prev_line == -1) {
            prev_line = common_lines[0];
        } else {
            int found = 0;
            for (int j = 0; j < common_count; j++) {
                if (common_lines[j] == prev_line) {
                    found = 1;
                    break;
                }
            }
            if (!found) {
                strcpy(simplified_path[simplified_count++], prev);
                prev_line = common_lines[0];
            }
        }
    }
    
    if (strcmp(simplified_path[simplified_count-1], end) != 0) {
        strcpy(simplified_path[simplified_count++], end);
    }
    
    // 计算换乘次数
    int transfer_count = 0;
    strcpy(prev, simplified_path[0]);
    prev_line = -1;
    
    for (int i = 1; i < simplified_count; i++) {
        strcpy(curr, simplified_path[i]);
        
        int prev_idx = -1, curr_idx = -1;
        for (int j = 0; j < station_count; j++) {
            if (strcmp(stations[j].name, prev) == 0) prev_idx = j;
            if (strcmp(stations[j].name, curr) == 0) curr_idx = j;
            if (prev_idx != -1 && curr_idx != -1) break;
        }
        
        if (prev_idx == -1 || curr_idx == -1) continue;
        
        int common_lines[MAX_STATIONS];
        int common_count = 0;
        for (int j = 0; j < stations[prev_idx].line_count; j++) {
            for (int k = 0; k < stations[curr_idx].line_count; k++) {
                if (stations[prev_idx].lines[j] == stations[curr_idx].lines[k]) {
                    common_lines[common_count++] = stations[prev_idx].lines[j];
                    break;
                }
            }
        }
        
        if (common_count == 0) {
            transfer_count++;
            prev_line = -1;
        } else if (prev_line == -1) {
            prev_line = common_lines[0];
        } else {
            int found = 0;
            for (int j = 0; j < common_count; j++) {
                if (common_lines[j] == prev_line) {
                    found = 1;
                    break;
                }
            }
            if (!found) {
                transfer_count++;
                prev_line = common_lines[0];
            }
        }
        strcpy(prev, curr);
    }
    
    // 输出结果
    for (int i = 0; i < simplified_count; i++) {
        if (i != 0) printf("-");
        printf("%s", simplified_path[i]);
    }
    printf("\n%d\n", 2 + transfer_count);
    
    return 0;
}

【华为od机试真题Python+JS+Java合集】【超值优惠】:Py/JS/Java合集

【华为od机试真题Python】:Python真题题库

【华为od机试真题JavaScript】:JavaScript真题题库

【华为od机试真题Java】:Java真题题库

【华为od机试真题C++】:C++真题题库

【华为od机试真题C语言】:C语言真题题库

【华为od面试手撕代码题库】:面试手撕代码题库

华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MISAYAONE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值