2024年华为OD机试真题-找城市 C/C++解法

基于二叉树思想,将每个城市使用结构体与指针联系起来,使用迭代遍历某一个城市为起点,不经过其某一个相邻城市,所能抵达的最大城市数量

#include <iostream>
#include <algorithm>
#include <list>

using namespace std;

// 城市
struct city
{
    list<city *> near_city_list; // 相邻城市
    int city_id;                 // 本城市的序号
};

/// @brief 搜索一个城市可扩展的最大城市个数,有一个条件就是放弃搜索 exclude_near 及其分支
/// @param city_find_start 从某一个城市开始找
/// @param exclude 排除掉的城市
/// @return
int calc_link_node(city *city_find_start, city *exclude)
{
    if (city_find_start->near_city_list.size() == 1)
    {
        return 1;
    }

    auto find_city = city_find_start->near_city_list.begin();
    int link_node_cnt = 1;

    while (find_city != city_find_start->near_city_list.end())
    {
        if ((*find_city)->city_id != exclude->city_id)
        {
            link_node_cnt += calc_link_node((*find_city), city_find_start);
        }
        find_city++;
    }

    return link_node_cnt;
}

// 找城市
static void HuaWei_OD_test29(void)
{
    int city_cnt; // 城市数量
    cin >> city_cnt;

    list<city *> all_city; // 全部的 city

    for (int i = 0; i < city_cnt - 1; i++)
    {
        int x, y;
        cin >> x >> y;

        auto find_city_left = std::find_if(
            all_city.begin(), all_city.end(),
            [=](city *a_city)
            {
                if (a_city->city_id == x)
                    return true;

                return false;
            });

        auto find_city_right = std::find_if(
            all_city.begin(), all_city.end(),
            [=](city *a_city)
            {
                if (a_city->city_id == y)
                    return true;

                return false;
            });

        // 一组新的配对
        if (find_city_left == all_city.end() &&
            find_city_right == all_city.end())
        {
            // 新建一个city信息
            city *new_city = new city;
            new_city->city_id = x;

            city *new_city_near = new city;
            new_city_near->city_id = y;

            new_city_near->near_city_list.push_back(new_city);
            new_city->near_city_list.push_back(new_city_near);

            all_city.push_back(new_city);
            all_city.push_back(new_city_near);
        }
        else
        {
            if (find_city_left != all_city.end() && find_city_right == all_city.end())
            {
                city *new_city_near = new city;
                new_city_near->city_id = y;

                new_city_near->near_city_list.push_back(*find_city_left);
                (*find_city_left)->near_city_list.push_back(new_city_near);
                all_city.push_back(new_city_near);
            }

            if (find_city_right != all_city.end() && find_city_left == all_city.end())
            {
                city *new_city_near = new city;
                new_city_near->city_id = x;

                new_city_near->near_city_list.push_back(*find_city_right);
                (*find_city_right)->near_city_list.push_back(new_city_near);
                all_city.push_back(new_city_near);
            }
        }
    }

    // 所有的城市间连接信息建立完毕,开始测试将 all_city 中某一个城市与其它城市连接全部切断
    // 统计每一个城市的DP

    list<pair<int, int>> city_dp_list; // pair first是城市编号, second是城市dp
    for (const auto &city : all_city)
    {
        int dp_max = 1;
        if (city->near_city_list.size() == 1)
        {
            dp_max = city_cnt - 1;
        }

        else
        {
            // 统计一个城市其相邻城市的相邻节点数目的最大值
            for (const auto &ele : city->near_city_list)
            {
                int link_node = calc_link_node(ele, city);
                if (link_node > dp_max)
                {
                    dp_max = link_node;
                }
            }
        }

        pair<int, int> city_dp;
        city_dp.first = city->city_id;
        city_dp.second = dp_max;
        city_dp_list.push_back(city_dp);
    }

    // 打印city_dp中最小的DP值的城市编号,如果有多个的话将其都打印出来

    // 首先将 list 按照DP值进行升序
    city_dp_list.sort([](const pair<int, int> &city_left, const pair<int, int> &city_right)
                      {
                    if(city_left.second < city_right.second)
                    return true;
                    return false; });

    // 选出DP值最小的,但是可能最小值有重复,将DP值非最小的从city_dp_list移除
    int min_dp = city_dp_list.front().second;
    while (city_dp_list.back().second != min_dp)
    {
        city_dp_list.pop_back();
    }

    // 将city_dp_list按照城市编号进行升序
    city_dp_list.sort([](const pair<int, int> &city_left, const pair<int, int> &city_right)
                      {
                    if(city_left.first < city_right.first)
                    return true;
                    return false; });

    for (const auto &city_dp_info : city_dp_list)
    {
        cout << city_dp_info.first << " ";
    }

    cout << endl;

    // 释放节点内存
    while (all_city.size() > 0)
    {
        auto allocate_city_mem = all_city.front();
        delete allocate_city_mem;
        all_city.pop_front();
    }
}

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

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值