华为机试真题练习汇总(71~80)

本文介绍了华为机试中的多项编程题目,包括字符串通配符匹配、百钱买百鸡问题、日期计算、参数解析、公共子串计算、尼科彻斯定理验证、火车进站排序以及整型数组合并,展示了不同领域的IT技术应用。
摘要由CSDN通过智能技术生成

华为机试真题练习汇总(71~80)

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

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

HJ71 字符串通配符

描述
问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符

注意:匹配时不区分大小写。

输入:
通配符表达式;
一组字符串。

输出:
返回不区分大小写的匹配结果,匹配成功输出true,匹配失败输出false

代码:

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

bool judge (char& c) {
    return (isalpha(c) || isalnum(c) || c == '.');
}

bool match(string p, string s) {
    int plen = p.size();
    int slen = s.size();
    // dp[i,j]: p[0,...,i]与s[0,...,j]是否匹配
    vector<vector<bool>> dp(plen + 1, vector<bool>(slen + 1, false));
    // 初始化
    dp[0][0] = true;
    // 状态转移
    for (int i = 1; i <= plen; i++) {
        dp[i][0] = dp[i - 1][0] && (p[i - 1] == '*'); // 首字符为'*'的情况
        for (int j = 1; j <= slen; j++) {
            if (p[i - 1] == '*') {
                dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
            } else {
                if (tolower(p[i - 1]) == tolower(s[j - 1])) // 要么两字符相等
                    dp[i][j] = dp[i - 1][j - 1];
                if (p[i - 1] == '?' && judge(s[j - 1])) // 要么?通配
                    dp[i][j] = dp[i - 1][j - 1];
            }
        }
    }
    return dp[plen][slen];
}

int main() {
    string p, s;
    cin >> p >> s;
    if (match(p, s)) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ72 百钱买百鸡问题

描述
公元五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
现要求你打印出所有花一百元买一百只鸡的方式。

输入描述:
输入任何一个整数,即可运行程序。

输出描述:
输出有数行,每行三个整数,分别代表鸡翁,母鸡,鸡雏的数量

代码:

#include <iostream>
using namespace std;

int main() {
    int x;
    cin >> x;
    for (int i = 0; i <= 20; i++)
        for (int j = 0; j <= 25; j++)
            for (int k = 0; k <= 100; k++) {
                if (i + j + k == 100 && 5 * i + 3 * j + k / 3.0 == 100.0)
                    cout << i << " " << j << " " << k << endl;
            }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ73 计算日期到天数转换

描述
根据输入的日期,计算是这一年的第几天。
保证年份为4位数且日期合法。

输入描述:
输入一行,每行空格分割,分别是年,月,日

输出描述:
输出是这一年的第几天

代码:

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

int isLeapYear(int y) {
    return (y % 400 == 0) || (y % 100 != 0 && y % 4 == 0);
}

int trans(int y, int m, int d) {
    const vector<int> days = {
        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    int sum = 0;
    for (int i = 0; i < m - 1; i++)
        sum += days[i];
    sum += d;
    if (isLeapYear(y) && m > 2)
        sum++;
    return sum;
}

int main() {
    int year, month, day;
    cin >> year >> month >> day;
    cout << trans(year, month, day) << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ74 参数解析

描述
在命令行输入如下命令:

xcopy /s c:\ d:\e,

各个参数如下:

参数1:命令字xcopy

参数2:字符串/s

参数3:字符串c:\

参数4: 字符串d:\e

请编写一个参数解析程序,实现将命令行各个参数解析出来。

解析规则:

1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” "d:“时,参数仍然是4个,第3个参数应该是字符串C:\program files,而不是C:\program,注意输出参数时,需要将”"去掉,引号不存在嵌套情况。
3.参数不定长

4.输入由用例保证,不会出现不符合要求的输入

输入描述:
输入一行字符串,可以有空格

输出描述:
输出参数个数,分解后的参数,每个参数都独占一行

代码:

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

int main() {
    string input;
    getline(cin, input);

    vector<string> parameters;
    string parameter = "";
    bool flag = false; // 记录是否进入引号内
    for (int i = 0; i < input.length(); i++) {
        if (flag) { // 在引号内
            if (input[i] != '\"')
                parameter.push_back(input[i]);
            else
                flag = false;
        } else { // 不在引号内
            if (input[i] == ' ') {
                // 遇到空格,截断
                parameters.push_back(parameter);
                parameter.clear();
            } else if (input[i] == '\"') {
                // 进入引号,设置flag
                flag = true;
            } else { // 其余添加进字符串
                parameter.push_back(input[i]);
            }
        }
    }
    parameters.push_back(parameter);
    cout << parameters.size() << endl;
    for (string& p : parameters)
        cout << p << endl;
        
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ75 公共子串计算

描述
给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。

注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。

输入描述:
输入两个只包含小写字母的字符串

输出描述:
输出一个整数,代表最大公共子串的长度

代码:

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

int LCSLength(string& s1, string& s2) {
    int M = s1.length(), N = s2.length();
    vector<vector<int>> dp(M + 1, vector<int>(N + 1, 0));
    int maxLen = 0;
    for (int i = 1; i <= M; i++)
        for (int j = 1; j <= N; j++) {
            if (s1[i - 1] == s2[j - 1])
                dp[i][j] = dp[i - 1][j - 1] + 1;
            else
                dp[i][j] = 0;
            if (dp[i][j] > maxLen)
                maxLen = dp[i][j];
        }
    return maxLen;
}

int main() 
{
    string s1, s2;
    cin >> s1 >> s2;
    cout << LCSLength(s1, s2) << endl;

    return 0;
}
// 64 位输出请用 printf("%lld")

HJ76 尼科彻斯定理

描述
验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

例如:

1^3=1

2^3=3+5

3^3=7+9+11

4^3=13+15+17+19

输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。

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

输出描述:
输出分解后的string

代码:

#include <iostream>
using namespace std;

int main() {
    int m;
    cin >> m;
    int mid = m * m;
    if (mid % 2 == 1) {
        int begin = mid - m / 2 * 2;
        int end = mid + m / 2 * 2;
        for (int i = begin; i <= end; i += 2) {
            if (i != end)
                cout << i << "+";
            else
                cout << i << endl;
        }
    } else {
        int begin = mid - 1 - (m / 2 - 1) * 2;
        int end = mid + 1 + (m / 2 - 1) * 2;
        for (int i = begin; i <= end; i += 2) {
            if (i != end)
                cout << i << "+";
            else
                cout << i << endl;
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

* HJ77 火车进站

描述
给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号,火车站只有一个方向进出,同时停靠在火车站的列车中,只有后进站的出站了,先进站的才能出站。
要求输出所有火车出站的方案,以字典序排序输出。

输入描述:
第一行输入一个正整数N(0 < N <= 10),第二行包括N个正整数,范围为1到10。

输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。

代码 1:

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

int main() 
{
    int n;
    cin >> n;
    vector<int> trains(n);
    for (int i = 0; i < n; i++)
        cin >> trains[i];

    vector<vector<int>> res;
    vector<int> seq;
    stack<int> s;
    // 回溯算法
    function<void(int)> dfs = [&](int index) {
        if (index >= n && s.empty()) {
            res.push_back(seq);
            return;
        }
        // 进栈
        if (index < n) {
            s.push(trains[index]);
            dfs(index + 1);
            // 回溯
            s.pop();
        }
        // 出栈
        if (!s.empty()) {
            seq.push_back(s.top());
            s.pop();
            dfs(index);
            // 回溯
            s.push(seq.back());
            seq.pop_back();
        }
    };

    dfs(0);
    sort(res.begin(), res.end());
    for (vector<int>& v : res) {
        for (int& x : v)
            cout << x << " ";
        cout << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

代码 2:

#include <algorithm>
#include <functional>
#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> trains(n);
    for (int i = 0; i < n; i++)
        cin >> trains[i];

    const vector<int> original_seq(trains);

    // 全排列前要先排序
    sort(trains.begin(), trains.end());

    auto check = [&](vector<int>& arr) -> bool {
        stack<int> s;
        int idx = 0;
        for (const int& train : original_seq) {
            s.push(train);
            while (!s.empty() && arr[idx] == s.top()) {
                s.pop();
                idx++;
            }
        }
        return s.empty();
    };

    // 全排列
    do {
        if (check(trains)) {
            for (int& x : trains)
                cout << x << " ";
            cout << endl;
        }
    } while (next_permutation(trains.begin(), trains.end()));

    return 0;
}
// 64 位输出请用 printf("%lld")

HJ80 整型数组合并

描述
题目标题:

将两个整型数组按照升序合并,并且过滤掉重复数组元素。
输出时相邻两数之间没有空格。

输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值

输出描述:
输出合并之后的数组

代码:

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

int main() {
    int n;
    vector<int> v;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        v.push_back(x);
    }
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        v.push_back(x);
    }

    sort(v.begin(), v.end());
    // 分组循环
    for (int i = 0; i < v.size(); i++) {
        while (i <= v.size() - 1 && v[i] == v[i + 1])
            i++;
        cout << v[i];
    }
    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、付费专栏及课程。

余额充值