华为机试真题练习汇总(11~20)

华为机试真题练习汇总(11~20)

题目来源:华为机试 - 牛客

标记 * 号的代表有难度的题目。

HJ11 数字颠倒

描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001

输入描述:
输入一个int整数

输出描述:
将这个整数以字符串的形式逆序输出

代码:

#include <iostream>
using namespace std;

int main() {
    int input;
    cin >> input;
    if (input == 0) {
        cout << "0" << endl;
        return 0;
    }
    string ans;
    while (input) {
        ans.push_back(input % 10 + '0');
        input /= 10;
    }
    cout << ans << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ12 字符串反转

描述
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

输入描述:
输入一行,为一个只包含小写字母的字符串。

输出描述:
输出该字符串反转后的字符串。

代码:

#include <algorithm>
#include <iostream>
using namespace std;

int main() {
    string s;
    cin >> s;
    reverse(s.begin(), s.end());
    cout << s << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ13 句子逆序

代码:

#include <vector>
#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    string s;
    getline(cin, s);
    stringstream ss(s);
    string word;

    vector<string> words;
    while (ss >> word)
        words.push_back(word);
    for (int i = words.size() - 1; i >= 0; i--)
    {
        if (i)
            cout << words[i] << ' ';
        else
            cout << words[i] << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ14 字符串排序

描述
给定 n 个字符串,请对 n 个字符串按照字典序排列。

输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。

输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。

代码:

#include <algorithm>
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<string> words;
    for (int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        words.push_back(s);
    }
    sort(words.begin(), words.end());
    for (string word : words)
        cout << word << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ15 求int型正整数在内存中存储时1的个数

描述
输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。

数据范围:保证在 32 位整型数字范围内

输入描述:
输入一个整数(int类型)

输出描述:
这个数转换成2进制后,输出1的个数

代码 1:

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;

    int count = 0;
    while (n) {
        count += n % 2;
        n >>= 1;
    }
    cout << count << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

代码 2:

n = n & (n-1),可以消去 n 二进制位中最右边的 1 个 1。

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int count = 0;
    while (n) {
        n &= (n - 1);
        count++;
    }
    cout << count << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

* HJ16 购物单

代码:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int N, m;
    cin >> N >> m;
    // 价格
    vector<vector<int>> prices(61, vector<int>(3, 0));
    // 满意度是指所购买的每件物品的价格与重要度的乘积
    vector<vector<int> > favors(61, vector<int>(3, 0));
    for (int i = 1; i <= m; i++) {
        int v, p, q;
        // v 是价格,p 是重要度,q 是主件编号
        cin >> v >> p >> q;
        int favor = v * p;
        if (q == 0) {
            prices[i][0] = v;
            favors[i][0] = favor;
        } else {
            if (prices[q][1] == 0) {
                prices[q][1] = v;
                favors[q][1] = favor;
            } else {
                prices[q][2] = v;
                favors[q][2] = favor;
            }
        }
    }
    // 状态数组
    vector<vector<int> > dp(m + 1, vector<int>(N + 1, 0));
    // 状态转移
    for (int i = 1; i <= m; i++)
        for (int j = 1; j <= N; j++) {
            int p0 = prices[i][0], f0 = favors[i][0];
            int p1 = prices[i][1], f1 = favors[i][1];
            int p2 = prices[i][2], f2 = favors[i][2];
            // 状态转移方程
            dp[i][j] = dp[i - 1][j];
            if (j >= p0)
                dp[i][j] =  max(dp[i - 1][j - p0] + f0, dp[i - 1][j]);
            if (j >= (p0 + p1))
                dp[i][j] =   max(dp[i - 1][j - (p0 + p1)] + f0 + f1, dp[i][j]);
            if (j >= (p0 + p2))
                dp[i][j] =   max(dp[i - 1][j - (p0 + p2)] + f0 + f2, dp[i][j]);
            if (j >= (p0 + p1 + p2))
                dp[i][j] =  max(dp[i - 1][j - (p0 + p1 + p2)] + f0 + f1 + f2, dp[i][j]);
        }
        cout<<dp[m][N]<<endl;
        return 0;
}
// 64 位输出请用 printf("%lld")

HJ17 坐标移动

代码:

#include <cctype>
#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    string str;
    cin >> str;

    stringstream ss(str);
    const char split = ';';
    string move;
    int x = 0, y = 0;
    while (getline(ss, move, split)) {
        char dir = move[0];
        bool judge = true;
        int distance = 0;
        for (int i = 1; i < move.length(); i++) {
            if (isdigit(move[i])) {
                distance = 10 * distance + move[i] - '0';
            } else {
                judge = false;
                break;
            }
        }
        if (judge) {
            switch (dir) {
                case 'A':
                    x -= distance;
                    break;
                case 'D':
                    x += distance;
                    break;
                case 'W':
                    y += distance;
                    break;
                case 'S':
                    y -= distance;
                    break;
                default:
                    break;
            }
        }
    }
    cout << x << "," << y << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

* HJ18 识别有效的IP地址和掩码并进行分类统计

代码:

#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

bool judge_ip(const string ip) {
    int j = 0;
    stringstream ss(ip);
    string seg;
    while (getline(ss, seg, '.'))
        if (++j > 4 || seg.empty() || stoi(seg) > 255)
            return false;
    return j == 4;
}

bool is_mask(const string ip) {
    stringstream ss(ip);
    string seg;
    unsigned int b = 0;
    while (getline(ss, seg, '.'))
        b = (b << 8) + stoi(seg);

    if (b == 0 || ~b == 0) {
        // 二进制下全是1或者全是0均为非法子网掩码
        return false;
    }
    b = ~b + 1;
    if ((b & (b - 1)) == 0)
        return true;
    return false;
}

bool is_private(const string ip) {
    istringstream iss(ip);
    string seg;
    vector<int> v;
    while (getline(iss, seg, '.'))
        v.push_back(stoi(seg));
    if (v[0] == 10)
        return true;
    if (v[0] == 172 && (v[1] >= 16 && v[1] <= 31))
        return true;
    if (v[0] == 192 && v[1] == 168)
        return true;
    return false;
}

int main()
{
    string line;
    int a = 0, b = 0, c = 0, d = 0, e = 0, err = 0, p = 0;
    while (cin >> line) {
        int split_index = line.find('~');
        string ip = line.substr(0, split_index);
        string mask = line.substr(split_index + 1);

        int idx = ip.find_first_of('.');
        int first = stoi(ip.substr(0, idx));
        // 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,
        // 也不属于不合法ip地址,计数时请忽略
        if(first == 0 || first == 127)
            continue;
        if (!judge_ip(mask) || !is_mask(mask))
            err++;
        else {
            if (is_private(ip))
                p++;
            if (first >= 1 && first <= 126)
                a++;
            else if (first >= 128 && first <= 191)
                b++;
            else if (first >= 192 && first <= 223)
                c++;
            else if (first >= 224 && first <= 239)
                d++;
            else if (first >= 240 && first <= 255)
                e++;
        }
    }
    cout << a << " " << b << " " << c << " " << d << " " << e << " " << err << " "
         << p << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

* HJ19 简单错误记录

描述
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。

处理:

1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是“相同”的错误记录。
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准

输入描述:
每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开

代码:

#include <iostream>
#include <string>
#include <map>
#include <deque>
using namespace std;

int main() {
    string str;
    map<string, int> cnt;
    deque<string> dq;
    while (getline(cin, str)) {
        str = str.substr(str.find_last_of('\\') + 1);
        int pos = str.find_last_of(' ');
        if (pos > 16)
            str = str.substr(pos - 16);
        if (!cnt.count(str))
            dq.push_back(str);
        cnt[str]++;
        // 只保留最后出现的八条错误记录
        if (dq.size() > 8)
            dq.pop_front();
    }
    for (auto s : dq)
        cout << s << " " << cnt[s] << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ20 密码验证合格程序

描述
密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有长度大于2的包含公共元素的子串重复 (注:其他符号不含空格或换行)

输入描述:
一组字符串。

输出描述:
如果符合要求输出:OK,否则输出NG

代码:

#include <iostream>
#include <vector>
using namespace std;

string passwordVerification(const string& s) {
    if (s.length() <= 8)
        return "NG";
    int n = s.length();
    // lower, upper, digit, other
    vector<bool> cnt(4, false);

    for (const char& ch : s) {
        if (islower(ch))
            cnt[0] = true;
        else if (isupper(ch))
            cnt[1] = true;
        else if (isdigit(ch))
            cnt[2] = true;
        else
            cnt[3] = true;
    }
    int count = 0;
    for (int i = 0; i < 4; i++)
        if (cnt[i])
            count++;
    if (count < 3)
        return "NG";
    for (int i = 0; i <= n - 6; i++) {
        string t1 = s.substr(i, 3);
        for (int j = i + 3; j <= n - 3; j++) {
            string t2 = s.substr(j, 3);
            if (t1 == t2)
                return "NG";
        }
    }
    return "OK";
}

int main()
{
    string pwd;
    while (getline(cin, pwd)) {
        cout << passwordVerification(pwd) << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

UestcXiye

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

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

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

打赏作者

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

抵扣说明:

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

余额充值