4.24华为笔试分享C++

腾个时间把代码贴一下

1.第一题: 无需实际建树,sort之后,进行二分查找即可,主要是到达叶节点后需要判断是否退出,否则会多一个L或者R

int main() {
    vector<int>nums;
    int temp;
    while (cin >> temp){
        nums.emplace_back(temp);
    }
    int target = nums.back();
    nums.pop_back();
//    nums = {1,2,3,4,5,6,7};
//    int target = 8;
    std::sort(nums.begin(), nums.end());
    int n = nums.size();
    int depth = 0;
    auto p = n + 1;
    while (p){
        depth++;
        p >>= 1;
    }
    if(target > nums.back()){
        cout << "S" + string(depth-2,'R') + "N";
        return 0;
    } else if(target < nums.front()){
        cout << "S" + string(depth-2,'L') + "N";
        return 0;
    }
    int l = 0;
    int r = n;
    int mid = 0;
    int d = 0;
    string ans = "S";
    while (l < r){
        mid = l + ((r-l)/2);
        if(nums[mid] == target){
            ans.push_back('Y');
            cout << ans << endl;
            return 0;
        }
        // 到达叶节点深度,进行判断
        if(d == depth - 2){
            break;
        }
        if(nums[mid] < target){
            ans.push_back('R');
            l = mid + 1;
        } else{
            ans.push_back('L');
            r = mid;
        }
        d++;
    }
    ans.push_back('N');
    cout << ans << endl;
    return 0;
}

2.第二题: 构造一个struct,其包含(int)总得分,(int)连续得分,(string)失分情况和(int)id.之后写一个cmp进行排序即可]

class player{
public:
    int total;
    int lianxu;
    string loss;
    int id;
    player() = default;
    player(int t,int l,string&& lo,int i):
        total(t),lianxu(l),loss(lo),id(i){};
};

int main()
{
    int n,m;
    cin >> n >> m;
    vector<string>arr;
    vector<player>players;
    for(int j = 0; j < n; j++){
        string temp;
        cin >> temp;
        int total = std::count(temp.begin(), temp.end(),'1');
        int cnt = 0;
        int lianxu = 0;
        string loss;
        for(int i = 0; i < temp.size(); i++){
            if(temp[i] == '1'){
                cnt++;
                lianxu = max(lianxu,cnt);
            } else{
                loss.push_back(i + '0');
                cnt = 0;
            }
        }
        players.emplace_back(total,lianxu,std::move(loss),j);
    }
    auto cmp = [&](const player& a,const player& b){
        if(a.total == b.total){
            if(a.lianxu == b.lianxu){
                if(a.loss == b.loss){
                    return a.id < b.id;
                }
                return a.loss > b.loss;
            }
            return a.lianxu > b.lianxu;
        }
        return a.total > b.total;
    };
    std::sort(players.begin(), players.end(),cmp);
    for(int i = 0; i < players.size(); i++){
        cout << players[i].id + 1;
        if(i != players.size() -1 ){
            cout << " ";
        }
    }
    return 0;
}

3.第三题.

读题可知: 这个有向图中的每个节点的出度都是1,并且edges[i] != i [关键条件]

那么,对于并查集的每个连通域来说,这个连通域内最多有一个环,最少有一个环

那么对于一个连通域,我们可以先任选一个点作为出发点,使用快慢指针,快慢指针相遇的位置肯定在环内.

之后从相遇处再绕着走一圈回到相遇处,并将遍历到的节点记录下来,这就是环.

H的计算方式就是 H = 环的长度 - (并查集的大小-环的长度)

int main()
{
    int n;
    cin >> n;
    vector<int>edges(n);
    for(int & edge : edges){
        int temp;
        cin >> temp;
        edge = temp;
    }
    vector<int>root(n,-1);
    vector<int>weight(n,1);
    vector<int>start;
    function<int(int )> find = [&](int x){
        if(root[x] == -1){
            return x;
        }
        return root[x] = find(root[x]);
    };
    auto to_union = [&](int x,int y){
        auto px = find(x);
        auto py = find(y);
        if(px == py){
            start.emplace_back(px);
        } else if(weight[px] > weight[py]){
            root[py] = px;
            weight[px] += weight[py];
        } else{
            root[px] = py;
            weight[py] += weight[px];
        }
    };
    for(int i = 0; i < n; i++){
        to_union(i,edges[i]);
    }
    int ans = INT_MIN;
    vector<int>vec;
    // y快指针,x慢指针
    for(auto x:start){
        auto y = edges[x];
        while (x != y){
            x = edges[x];
            y = edges[edges[y]];
        }
        vector<int>temp = {x};
        y = edges[y];
        while (x != y){
            temp.emplace_back(y);
            y = edges[y];
        }
        int H = (int)temp.size() - (weight[find(x)] - (int)temp.size());
        if(H > ans){
            ans = H;
            vec = temp;
        } else if(H == ans){
            auto k1 = *std::max_element(vec.begin(), vec.end());
            auto k2 = *std::max_element(temp.begin(), temp.end());
            if(k2 > k1){
                vec = temp;
            }
        }
    }
    rotate(vec.begin(), min_element(vec.begin(),vec.end()),vec.end());
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i];
        if(i != vec.size() - 1){
            cout << " ";
        }
    }
    return 0;
}

全部评论
等你代码,兄弟
点赞 回复 分享
发布于 04-25 11:06 广西
第三题思路一样 卡92%
点赞 回复 分享
发布于 04-25 17:37 上海

相关推荐

10-05 23:02
东北大学 Java
我说句实话啊:那时候看三个月培训班视频,随便做个项目背点八股,都能说3 40w是侮辱价
点赞 评论 收藏
分享
一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
评论
4
20
分享
牛客网
牛客企业服务