华为机试真题练习汇总(91~100)

该博客汇总了华为机试真题(91 - 100),题目来源为华为机试 - 牛客。包含走方格方案数、找最长数字串、数组分组等题目,介绍了各题描述、输入输出要求,并给出对应代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

华为机试真题练习汇总(91~100)

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

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

HJ91 走方格的方案数

描述
请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。

注:沿棋盘格之间的边缘线行走

输入描述:
输入两个正整数n和m,用空格隔开。(1≤n,m≤8)

输出描述:
输出一行结果

代码:

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

int main() {
    int n, m;
    cin >> n >> m;
    // 状态矩阵
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, 1));
    // 初始化
    for (int i = 0; i <= n; i++)
        dp[i][0] = 1;
    for (int j = 0; j <= m; j++)
        dp[0][j] = 1;
    // 状态转移
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
    cout << dp[n][m] << endl;

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

HJ92 在字符串中找出连续最长的数字串

描述
输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置)
本题含有多组样例输入。

输入描述:
输入一个字符串。1<=len(字符串)<=200

输出描述:
输出字符串中最长的数字字符串和它的长度,中间用逗号间隔。如果有相同长度的串,则要一块儿输出(中间不要输出空格)。

代码:

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

int main() {
    string s;
    while (cin >> s) {
        vector<string> digitStr;
        int maxLen = 0;
        int i = 0;
        while (i < s.length()) {
            if (isdigit(s[i])) {
                int j = i + 1;
                while (isdigit(s[j]) && j < s.length())
                    j++;
                // s[i,j-1] 是一个数字子串
                string d = s.substr(i, j - i);
                digitStr.push_back(d);
                maxLen = max(maxLen, (int)d.length());
                i = j + 1;
            } else {
                i++;
            }

        }
        for (string& d : digitStr)
            if (d.length() == maxLen)
                cout << d;
        cout << "," << maxLen << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ93 数组分组

描述
输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),不是5的倍数也不是3的倍数能放在任意一组,可以将数组分为空数组,能满足以上条件,输出true;不满足时输出false。

输入描述:
第一行是数据个数,第二行是输入的数据

输出描述:
返回true或者false

代码:

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

int main() {
    int n;
    cin >> n;
    vector<int> other;
    int sum5 = 0, sum3 = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x % 5 == 0)
            sum5 += x;
        else if (x % 3 == 0)
            sum3 += x;
        else
            other.push_back(x);
    }
    // 枚举所有组合的不重复和
    unordered_set<int> s;
    s.insert(0); // 0 代表空数组
    for (int& x : other) {
        unordered_set<int> tmp(s);
        for (auto it : tmp)
            s.insert(it + x);
    }
    bool found = false;
    int sum = accumulate(other.begin(), other.end(), 0);
    for (auto it : s)
        if (it + sum3 == sum5 + sum - it) {
            found = true;
            break;
        }
    cout << (found ? "true" : "false") << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ94 记票统计

描述
请实现一个计票统计系统。你会收到很多投票,其中有合法的也有不合法的,请统计每个候选人得票的数量以及不合法的票数。
(注:不合法的投票指的是投票的名字不存在n个候选人的名字中!!)

输入描述:
第一行输入候选人的人数n,第二行输入n个候选人的名字(均为大写字母的字符串),第三行输入投票人的人数,第四行输入投票。

输出描述:
按照输入的顺序,每行输出候选人的名字和得票数量(以" : "隔开,注:英文冒号左右两边都有一个空格!),最后一行输出不合法的票数,格式为"Invalid : "+不合法的票数。

代码:

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

int main() {
    int n;
    cin >> n;
    vector<string> list;
    set<string> s;
    for (int i = 0; i < n; i++) {
        string name;
        cin >> name;
        list.push_back(name);
        s.insert(name);
    }
    int m;
    cin >> m;
    int valid = 0;
    unordered_map<string, int> mp;
    for (int i = 0; i < m; i++) {
        string name;
        cin >> name;
        if (s.count(name)) {
            mp[name]++;
            valid++;
        }
    }
    // print
    for (auto& name : list)
        cout << name << " : " << mp[name] << endl;
    cout << "Invalid : " << m - valid << endl;
    
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ95 人民币转换

描述
考试题目和要点:

1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。

2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。

3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如6007.14,应写成“人民币陆仟零柒元壹角肆分“。
4、10应写作“拾”,100应写作“壹佰”。例如,1010.00应写作“人民币壹仟零拾元整”,110.00应写作“人民币壹佰拾元整”
5、十万以上的数字接千不用加“零”,例如,30105000.00应写作“人民币叁仟零拾万伍仟元整”

输入描述:
输入一个double数

输出描述:
输出人民币格式

代码:

#include <iostream>
using namespace std;

// 构建个位的字典(数组)
const string gewei[10] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};

// 获取元钱的函数接口,即小数点之前的部分
void Get_Before_Plot(string str) {
    if (str == "0") {
        return;
    }
    for (int i = str.size() - 1, j = 0; i >= 0; i--, j++) {
        // i表示这是数字的第几位,j表示字符串下标
        if (str[j] != '0') { // 将当前位置的数字转为中文
            if (!(str[j] == '1' && i % 4 == 1)) // 10应写作“拾”,而不是“壹零”
                cout << gewei[str[j] - '0'];
        }
        if (i != 0) { // 当前不是个位
            if (i % 8 == 0 && i >= 8) { // 亿位
                cout << "亿";
            }
            if (i % 4 == 0 && i % 8 != 0) { // 万位
                cout << "万";
                if (str[j + 1] == '0') // 如果千位为0
                    cout << "零";
            }
            if (i % 4 == 3 && str[j] != '0') { // 千
                cout << "仟";
                if (str[j + 1] == '0' && str[j + 2] != '0') // 百位为0
                    cout << "零";
            }
            if (i % 4 == 2 && str[j] != '0') { //百
                cout << "佰";
                if (str[j + 1] == '0' && str[j + 2] != '0') // 十位为0
                    cout << "零";
            }
            if (i % 4 == 1 && str[j] != '0') // 十位
                cout << "拾";
        }
    }
    return;
}

// 获取角分零钱的函数接口,即小数点之后的部分
void Get_After_Plot(string str) {
    if (str == "00") {
        cout << "整";
        return;
    }
    if (str[0] > '0') {
        cout << gewei[str[0] - '0'] << "角";
    }
    if (str[1] > '0') {
        cout << gewei[str[1] - '0'] << "分";
    }
    return;
}

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

    //
    string str1 = money.substr(0, money.find('.'));
    // 获取小数点后的子字符串
    string str2 = money.substr(money.find('.') + 1);
    // 输出人民币
    cout << "人民币";
    // 输出元钱
    Get_Before_Plot(str1);
    if (str1 != "0")
        cout << "元";
    // 输出角分零钱
    Get_After_Plot(str2);
    // 换行
    cout << endl;
}
// 64 位输出请用 printf("%lld")

HJ96 表示数字

描述
将一个字符串中所有的整数前后加上符号“*”,其他字符保持不变。连续的数字视为一个整数。

输入描述:
输入一个字符串。

输出描述:
字符中所有出现的数字前后加上符号“*”,其他字符保持不变。

代码:

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

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

    bool flag = false;
    for (char& c : input) {
        if (isdigit(c)) {
            if (flag == false) {
                // 进入数字子串
                cout << '*';
                flag = true;
            }
            cout << c;
        } else {
            if (flag == true) {
                // 退出数字子串
                cout << '*';
                flag = false;
            }
            cout << c;
        }
    }
    if (isdigit(input[input.length() - 1]))
        cout << '*';

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

HJ97 记负均正

描述
首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。
0即不是正整数,也不是负数,不计入计算。如果没有正数,则平均值为0。

输入描述:
首先输入一个正整数n,
然后输入n个整数。

输出描述:
输出负数的个数,和所有正整数的平均值。

代码:

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

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

    int cnt_neg = 0, sum = 0, cnt_pos = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x > 0) {
            sum += x;
            cnt_pos++;
        } else if (x < 0)
            cnt_neg++;
    }
    cout << cnt_neg << " ";
    if (cnt_pos) {
        double avg = 1.0 * sum / cnt_pos;
        printf("%.1f\n", avg);
    } else
        cout << "0.0" << endl;

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

HJ98 自动售货系统

链接:https://www.nowcoder.com/practice/cd82dc8a4727404ca5d32fcb487c50bf

代码:

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

const vector<int>  price = {2, 3, 4, 5, 8, 6}; // 商品价格
int money = 0; //投入的钱

// 通过字符c分割字符串
vector<string> split(string str, const char c) {
    vector<string> res;
    istringstream iss(str); // 字符串流输入
    string temp = "";
    while (getline(iss, temp, c)) // 根据流输入分割
        res.push_back(temp);
    return res;
}

// 初始化函数
void init(vector<int>& a, vector<int>& b, string& s) {
    money = 0; // 初始化投入的钱
    s = s.substr(2, s.length() - 2); // 去掉前面的r和空格
    a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = 0;
    b[0] = b[1] = b[2] = b[3] = 0;
    int i = 0;
    // 判别是前面部分商品价格还是后面部分零钱盒
    bool flag = false;
    for (auto c : s) {
        if (isdigit(c) && !flag) // 数字且是价格
            a[i] = a[i] * 10 + (c - ' 0'); // 根据字符计算数字
        else if (isdigit(c) && flag) //数字且是零钱
            b[i] = b[i] * 10 + (c - '0'); // 根据字符计算数字
        else if (c == ' ') { // 遇到空格换成零钱
            flag = true;
            i = 0;
        } else if (c == '-') // 遇到-后移一位商品或零钱
            i++;
    }
    cout << "S001:Initialization is successful" << endl;
}

// 投币函数
void pay(vector<int>& a, vector<int>& b, string& s) {
    int num = 0;
    for (auto& c : s)
        if (isdigit(c)) // 只计算数字部分
            num = num * 10 + (c - '0'); // 一次只投一张
    if (num == 1 || num == 2 || num == 5 || num == 10) { // 投入合法的币种
        if (num > 2 && num > (b[0] + b[1] * 2)) {
            // 存钱盒中1元和2元面额钱币总额小于本次投入的钱币面额
            cout << "E003:Change is not enough, pay fail" << endl;
        } else if ((a[0] || a[1] || a[2] || a[3] || a[4] || a[5]) == 0) {
            // 商品全部为0
            cout << "E005:All the goods sold out" << endl;
        } else {
            //零钱盒中钱数增加
            if (num == 1 || num == 2)
                b[num - 1]++;
            else if (num == 5)
                b[2]++;
            else b[3]++;
            money += num; // 投入的总钱数增加
            cout << "S002:Pay success,balance=" << money << endl;
        }
    } else {
        // 不合法币种
        cout << "E002:Denomination error" << endl;
    }
}

// 购买函数
void buy(vector<int>& a, vector<int>& b, string& s) {
    // 检查命令是否是4位,第三位是否为A,第四位是否数字1-6
    if (s.length() == 4 && (s[2] == 'A') && (s[3] - '0' < 7) && isdigit(s[3]) &&
            (s[3] != '0')) {
        if (a[s[3] - '1'] == 0) {
            // 该商品的售罄
            cout << "E007:The goods sold out" << endl;
        } else if (price[s[3] - '1'] > money) {
            // 该商品价格大于投入的钱
            cout << "E008:Lack of balance" << endl;
        } else { // 成功购买
            money -= price[s[3] - '1']; // 投入的钱要减去买的商品
            a[s[3] - '1']--;
            cout << "S003:Buy success,balance=" << money << endl;
        }
    } else {
        // 输入命令不合法,商品不存在
        cout << "E006:Goods does not exist" << endl;
    }
}

// 退币函数
void back(vector<int>& coins) {
    int a = 0, b = 0, c = 0, d = 0; // 四个币种
    if (money == 0) {
        // 投入的没有钱了,不用退
        cout << "E009:Work failure" << endl;
    } else {
        d = money / 10; // 优先退大币额的数量
        if (d <= coins[3]) { // 10块的钱够退
            money = money % 10;
            coins[3] -= d;
        } else { // 10块的钱不够退
            d = coins[3]; // 全部退完
            coins[3] = 0;
            money -= d * 10; // 剩余要退的
        }
        c = money / 5; // 再计算要退的5块钱的数量
        if (c <= coins[2]) { // 5块的钱够退
            money = money % 5;
            coins[2] -= c;
        } else { // 5块的钱不够退
            c = coins[2]; // 全部退完
            coins[2] = 0;
            money -= d * 5; // 剩余要退的
        }
        b = money / 2; // 再计算要退的2块钱的数量
        if (b <= coins[1]) { // 2块的钱够退
            money = money % 2;
            coins[1] -= b;
        } else { // 2块的钱不够退
            b = coins[1]; // 全部退完
            coins[1] = 0;
            money -= d * 2; // 剩余要退的
        }
        a = money;  // 再计算要退的1块钱的数量
        if (a <= coins[0]) { // 1块的钱够退
            coins[0] -= a;
            money = 0;
        } else { // 1块的钱不够退
            coins[0] = 0;
            money -= a;
        }
        cout << "1 yuan coin number=" << a << endl;
        cout << "2 yuan coin number=" << b << endl;
        cout << "5 yuan coin number=" << c << endl;
        cout << "10 yuan coin number=" << d << endl;
    }
}

// 重载比较
bool cmp(pair<pair<string, int>, int>& a, pair<pair<string, int>, int>& b) {
    if (a.second != a.second) // 优先比较商品数量
        return a.second > b.second;
    else //再比较商品名字
        return a.first.first < b.first.first;
}

// 查询函数
void query(vector<int>& a, vector<int>& b, string& s) {
    if (s[1] == ' ' && s.length() == 3) { // 检查查询命令的合法性
        if (s[2] == 0) { // 类别为0
            vector<pair<pair<string, int>, int> > temp;
            for (int i = 0; i < 6; i++) {
                // 商品信息入vector方便排序输出
                temp.push_back(make_pair(make_pair("A" + char(i + 1), price[i]), a[i]));
            }
            sort(temp.begin(), temp.end(), cmp); // 按照重载后的比较排序
            // 输出
            for (int i = 0; i < 6; i++) 
                cout << temp[i].first.first << " " << temp[i].first.second << " " <<
                     temp[i].second << endl;
        } else if (s[2] == 1) { // 类别为1
            cout << "1 yuan coin number=" << b[0] << endl
                 << "2 yuan coin number=" << b[1] << endl
                 << "5 yuan coin number=" << b[2] << endl
                 << "10 yuan coin number=" << b[3] << endl;
        } else
            cout << "E010:Parameter error" << endl;
    } else
        cout << "E010:Parameter error" << endl;
}

int main()
{
    string s;
    vector<int> goods(6, 0);
    vector<int> coins(4, 0);
    while (getline(cin, s)) {
        vector<string> orders = split(s, ';');
        for (auto c : orders) {
            switch (c[0]) {
                case 'r': // 初始化
                    init(goods, coins, c);
                    break;
                case 'p': // 投币
                    pay(goods, coins, c);
                    break;
                case 'b': // 购买商品
                    buy(goods, coins, c);
                    break;
                case 'c': // 退币
                    back(coins);
                    break;
                case 'q': // 查询
                    query(goods, coins, c);
                    break;
            }
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ99 自守数

描述
自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n(包括n)以内的自守数的个数。

输入描述:
int型整数

输出描述:
n以内自守数的数量。

代码:

#include <iostream>
using namespace std;

bool isSelfNum(int x) {
    string s1 = to_string(x), s2 = to_string(x * x);
    return s1 == s2.substr(s2.length() - s1.length());
}

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

    int count = 0;
    for (int i = 0; i <= n; i++)
        if (isSelfNum(i))
            count++;
    cout << count << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ100 等差数列

描述
等差数列 2,5,8,11,14。。。。
(从 2 开始的 3 为公差的等差数列)
输出求等差数列前n项和。

输入描述:
输入一个正整数n。

输出描述:
输出一个相加后的整数。

代码:

#include <iostream>
using namespace std;

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

    int begin = 2, end = 2 + 3 * (n - 1);

    cout << (begin + end)*n / 2 << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

UestcXiye

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

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

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

打赏作者

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

抵扣说明:

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

余额充值