首页 > 华为OD机试为什么会挂那么多?
头像
还是啥都不说了吧
编辑于 2022-05-10 17:28
+ 关注

华为OD机试为什么会挂那么多? 内部员工回复

最近一段时间,发现华为OD的机试总是很多人都挂掉,很多人得0分我就认为是平台不会用,或者直接放弃了。
但有些人只考了十几分、几十分,我就想不通了,题到底有多难呢?
抱着这个疑问,我也申请了一次机考,并于2022年2月1号的凌晨把它给做了。
下面说一下我的经验。

设备:
机考需要防作弊,所以需要一台有摄像头的电脑。
考试期间,需要让屏幕处于录制状态,手机也要扫一个二维码,并保持在那个界面不动。
我是没有带摄像头的电脑的,但我有个笔记本。笔记本有摄像头,但键盘和屏幕不适合敲代码。于是:
我把笔记本当摄像头和主机,外接了一个屏幕和一个键盘。
手机充上电,因为是凌晨,并且正好是大过年的 ,不会有人给我打电话。

开始之前:
有好几个步骤要点,比如签名啊、启动监控啊之类的。

一切就绪,开考:
首先是一个例子,输入两个数字 a和b,让你求 a+b 。 刚开始我没看明白,以为题目这么简单吗? 思考了十分钟,才发现它是一个例子。

第一题,非严格递增连续数字序列
大概是给你一个字符串,长度题目好像给了, 最大不超过255个字符(这就看出来,暴力就行,不需要花里胡哨的算法),让你找出最长的一个连续的数字(要求非严格递增,即 12234 这种,递增但不要求严格递增,但不能递减),比如  abasdf12234sdaf112 , 最长连续数字是 12234,长度是5,让你返回这个长度。
这个太简单了,直接暴力解决,AC了。

我的代码(满分,做题用时 7分24秒):
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;
 
bool isNum(char c)
{
    return c >= '0' && c <= '9';
}
int main()
{
    string str;
    cin >> str;
    if (str.size() == 0)
    {
        return 0;
    }
    int maxlen = -1;
    for (int i = 0; i < str.length(); i++)
    {
        if (isNum(str[i]))
        {
            maxlen = max(maxlen,1);
            int tmplen = 1;
            for (int j = i+1; j < str.length(); j++)
            {
                if (isNum(str[j]) && str[j] >= str[j-1])
                {
                    tmplen++;
                }
                else
                {
                    break;
                }
            }
            maxlen = max(maxlen, tmplen);
        }
    }
    if (maxlen == -1)
    {
        maxlen = 0;
    }
    cout << maxlen << endl;
    return 0;
 
}



第二题,查找众数及中位数
题目很复杂,先给出一个 众数 的概念,就是数组中出现次数最多的数字。
又给出一个 中位数的概念,就是从小到大排序后,中间那个数。如果数组大小是偶数,则取中间两个相加再除以2.
让求  给定的数组中的众数, 如果有多个,就把众数组成一个新的数组,求新数组的中位数。

这道题我在输入的时候,就把数组搞了个map,以数字做key,出现的次数做value,并用一个临时变量记录最大的 value。
然后再从数组中找出value等于这个 maxvalue 的 key,放入一个vector。因为map本身就是排过序的,所以不用对vector再排序了。
然后看下vector的大小,是偶数的话,取 中间两个相加除以2, 是奇数的话,直接返回中间那个,搞定了。
这个方法并不是最优解,但能过就行。

我的代码(满分,做题用时 11分17秒)
#include <string>
#include <iostream>
#include <stdlib.h>
#include <map>
#include <vector>
#include <utility>
using namespace std;
int main()
{
    map<int,int> colects;
    int n = 0;
    int maxNum = 0;
    while (cin>>n)
    {
        auto it = colects.find(n);
        if (it != colects.end())
        {
            it->second++;
            maxNum = max(maxNum, it->second);
        }
        else
        {
            colects.insert(std::make_pair(n, 1));
            maxNum = max(maxNum, 1);
        }
    }
 
    vector<int> middles;
    for (auto it = colects.begin(); it != colects.end(); it++)
    {
        if (it->second == maxNum)
        {
            middles.push_back(it->first);
        }
    }
 
    if (middles.size()%2)
    {
        cout << middles[middles.size() / 2] << endl;
    }
    else
    {
        cout << (middles[middles.size() / 2 - 1] + middles[middles.size() / 2]) / 2 << endl;
    }
 
    return 0;
}



第三题:【考古学家 
有一大堆墓碑碎片,每个碎片就是一个字符串,让你给出排列组合的所有可能,要去重。
比如  a  b c   这么3块墓碑,排列组合有:
abc acb bac bca cab cba  这么多种。
比如 墓碑是 a b ab ,则 要记得去重,结果是  abab aabb baab baba abba , 其实还有一个 abab,因为和第一个重了,所以要去掉。加粗的是 那个连着的 ab 。
这个就暴力,用递归就可以了。

我的代码(满分,做题用时27分6秒
#include <string>
#include <iostream>
#include <stdlib.h>
#include <map>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
 
bool checkAnyNoVisited(vector<int> &visited)
{
    bool n = true;
    for_each(visited.begin(), visited.end(), [&](int x) { n &= x;});
    return n;
}
void function(vector<string> &colects, map<string, bool> &result, string & str, vector<int> &visited)
{
    //如果尚有未访问的,则继续,否则push到map里
    if (!checkAnyNoVisited(visited))
    {
        for (int i = 0; i < colects.size(); i++)
        {
            if (visited[i] == 0)
            {
                visited[i] = 1;
                string tempstr = str + colects[i];
                function(colects, result, tempstr, visited);
                visited[i] = 0;
            }
        }
    }
    else
    {
        result.insert(std::make_pair(str, true));
    }
 
    return;
};
 
int main()
{
    int n;
    vector<string> colects;
    cin >> n;
    while (n)
    {
        n--;
        string s;
        cin >> s;
        colects.push_back(s);
    }
 
    map<string, bool> result;
     
    for (int i = 0; i < colects.size(); i++)
    {
        vector<int> visited(colects.size(), 0);
        visited[i] = 1;
        string str = colects[i];
        function(colects, result, str, visited);
        visited[i] = 0;
    }
 
    for (auto it = result.begin(); it != result.end(); it++)
    {
        cout << it->first << endl;
    }
 
    return 0;
}



感慨:
感觉三道题都很简单,我用了一小时十分钟。
很多题目已经给出了 一些入参的边界,我发现边界都不是很极端,好多东西都可以暴力解决。


最后打个广告:







更多模拟面试

全部评论

(19) 回帖
加载中...
话题 回帖