华为机试真题练习汇总(81~90)

华为机试真题练习汇总(81~90)

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

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

HJ81 字符串字符匹配

描述
判断短字符串S中的所有字符是否在长字符串T中全部出现。
请注意本题有多组样例输入。

输入描述:
输入两个字符串。第一个为短字符串,第二个为长字符串。两个字符串均由小写字母组成。

输出描述:
如果短字符串的所有字符均在长字符串中出现过,则输出字符串"true"。否则输出字符串"false"。

代码:

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

// bool isSubStr(string& s1, string& s2) {
//     int len1 = s1.length(), len2 = s2.length();
//     for (int i = 0; i <= len2 - len1; i++)
//         if (s2.substr(i, len1) == s1)
//             return true;
//     return false;
// }

bool isAllOccurred(const string& s1, const string& s2) {
    vector<bool> dict1(26, false);
    for (const char& c : s1)
        dict1[c - 'a'] = true;
    vector<bool> dict2(26, false);
    for (const char& c : s2)
        dict2[c - 'a'] = true;
    for (int i = 0; i < 26; i++)
        if (dict1[i] && !dict2[i])
            return false;
    return true;
}

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

** HJ82 将真分数分解为埃及分数

描述
分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。
注:真分数指分子小于分母的分数,分子和分母有可能gcd不为1!
如有多个解,请输出任意一个。

输入描述:
输入一个真分数,String型

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

代码:

#include <iostream>
using namespace std;

int main() {
    // a/b = 1/(x+1) + 1/(x+1) * (a-y)/b
    // 其中,x = b/a,y = b%a
    long a, b; // 分别是分子分母
    char op; // 除号
    while (cin >> a >> op >> b) {
        while (a != 1) { //直到最后的a为1
            if (b % a == 0) { //先去掉公因子
                b = b / a;
                break;
            }
            //按照公式推算运算
            long x = b / a;
            long y = b % a;
            cout << 1 << op << x + 1 << "+";
            a -= y;
            b *= x + 1;
        }
        cout << 1 << op << b << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ83 二维数组操作

描述

在这里插入图片描述

输入描述:
输入数据按下列顺序输入:
1 表格的行列值
2 要交换的两个单元格的行列值
3 输入要插入的行的数值
4 输入要插入的列的数值
5 输入要查询的单元格的坐标

输出描述:
输出按下列顺序输出:
1 初始化表格是否成功,若成功则返回0, 否则返回-1
2 输出交换单元格是否成功
3 输出插入行是否成功
4 输出插入列是否成功
5 输出查询单元格数据是否成功

代码:

#include <iostream>
using namespace std;

int main() {
    int row, col; // 表格的行列值
    while (cin >> row >> col) {
        // 初始化表格是否成功,若成功则返回0, 否则返回-1
        if (row > 0 && row <= 9 && col > 0 && col <= 9)
            cout << 0 << endl;
        else
            cout << -1 << endl;
        // 交换坐标
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        if (x1 < 0 || x1 >= row || y1 < 0 || y1 >= col
                || x2 < 0 || x2 >= row || y2 < 0 || y2 >= col)
            cout << -1 << endl;
        else
            cout << 0 << endl;
        // 在第x行上方添加一行
        int x;
        cin >> x;
        if (x < 0 || x >= row || row >= 9)
            cout << -1 << endl;
        else
            cout << 0 << endl;
        // 在第 y 列左边添加一列
        int y;
        cin >> y;
        if (y < 0 || y >= col || col >= 9)
            cout << -1 << endl;
        else
            cout << 0 << endl;
        // 查找坐标为 (x,y) 的单元格的值
        cin >> x >> y;
        if (x < 0 || x >= row || y < 0 || y >= col)
            cout << -1 << endl;
        else
            cout << 0 << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ84 统计大写字母个数

描述
找出给定字符串中大写字符(即’A’-‘Z’)的个数。
字符串中可能包含空格或其他字符。

输入描述:
对于每组样例,输入一行,代表待统计的字符串

输出描述:
输出一个整数,代表字符串中大写字母的个数

代码:

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

int main() {
    string s;
    getline(cin, s);
    int count = 0;
    for (char& c : s)
        if (isupper(c))
            count++;

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

HJ85 最长回文子串

描述
给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。
所谓回文串,指左右对称的字符串。
所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串

输入描述:
输入一个仅包含小写字母的字符串

输出描述:
返回最长回文子串的长度

代码:

#include <iostream>
using namespace std;

int palindromeLength(string& s, int low, int high) {
    while (low >= 0 && high < s.length() && s[low] == s[high]) {
        low--;
        high++;
    }
    int len = high - low - 1;
    return len;
}

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

    int maxLen = 1;
    for (int i = 1; i < s.length() - 1; i++) {
        int len1 = palindromeLength(s, i, i);
        int len2 = palindromeLength(s, i, i + 1);
        if (max(len1, len2) > maxLen)
            maxLen = max(len1, len2);
    }
    cout << maxLen << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

HJ86 求最大连续bit数

描述
求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1

输入描述:
输入一个int类型数字

输出描述:
输出转成二进制之后连续1的个数

代码 1:

#include <iostream>
using namespace std;

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

    int count = 0, max_count = 0;
    while (n) {
        if (n % 2 == 1) // 最后一位为1
            count++;
        else { // 遇到不为1
            max_count = max(max_count, count); // 更新最大值
            count = 0; // 重置
        }
        n /= 2; // 去掉最后一位
    }
    max_count = max(max_count, count); // 最后一次更新最大值
    cout << max_count << endl;

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

代码 2:

#include<iostream>
using namespace std;

int main() {
    int n;
    while (cin >> n) {
        int count = 0;
        for (; n != 0; count++) // 统计能够运算多少次
            n &= n << 1; // 与自己左移一位后比较
        cout << count << endl;
    }
    return 0;
}

// 64 位输出请用 printf("%lld")

HJ87 密码强度等级

描述
密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。

一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符

二、字母:
0 分: 没有字母
10 分: 密码里的字母全都是小(大)写字母
20 分: 密码里的字母符合”大小写混合“

三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字

四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号

五、奖励(只能选符合最多的那一种奖励):
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号

最后的评分标准:
>= 90: 非常安全
>= 80: 安全(Secure)
>= 70: 非常强
>= 60: 强(Strong)
>= 50: 一般(Average)
>= 25: 弱(Weak)
>= 0: 非常弱(Very_Weak)

对应输出为:

VERY_SECURE
SECURE
VERY_STRONG
STRONG
AVERAGE
WEAK
VERY_WEAK

请根据输入的密码字符串,进行安全评定。

注:
字母:a-z, A-Z
数字:0-9
符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)
!"#$%&'()*+,-./ (ASCII码:0x21~0x2F)
:;<=>?@ (ASCII码:0x3A~0x40)
[]^_` (ASCII码:0x5B~0x60)
{|}~ (ASCII码:0x7B~0x7E)

提示:
1 <= 字符串的长度<= 300

输入描述:
输入一个string的密码

输出描述:
输出密码等级

代码:

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

bool issignal(char& c) {
    const string signalStr = "!\"#$%&'()*+,-./[\\]^_`{|}~";
    if (find(signalStr.begin(), signalStr.end(), c) != signalStr.end())
        return true;
    else
        return false;
}

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

    int score = 0;
    // 密码长度
    int len = pwd.length();
    if (len <= 4)
        score += 5;
    else if (len < 8)
        score += 10;
    else if (len >= 8)
        score += 25;
    // 统计字母、数字、符号
    int lower = 0, upper = 0, digit = 0, signal  = 0;
    for (char& c : pwd) {
        if (islower(c))
            lower++;
        else if (isupper(c))
            upper++;
        else if (isdigit(c))
            digit++;
        else if (issignal(c))
            signal++;
    }
    // 字母
    if ((lower > 0 && upper == 0) || (lower == 0 && upper > 0))
        score += 10;
    else if (lower > 0 && upper > 0)
        score += 20;

    if (digit == 1)
        score += 10;
    else if (digit > 1)
        score += 20;

    if (signal == 1)
        score += 10;
    else if (signal > 1)
        score += 25;

    int alpha = lower + upper;
    if (lower > 0 && upper > 0 && digit > 0 && signal > 0)
        score += 5;
    else if (alpha > 0 && digit > 0 && signal > 0)
        score += 3;
    else if (alpha > 0 && digit > 0)
        score += 2;

    if (score >= 90)
        cout << "VERY_SECURE" << endl;
    else if (score >= 80)
        cout << "SECURE" << endl;
    else if (score >= 70)
        cout << "VERY_STRONG" << endl;
    else if (score >= 60)
        cout << "STRONG" << endl;
    else if (score >= 50)
        cout << "AVERAGE" << endl;
    else if (score >= 25)
        cout << "WEAK" << endl;
    else if (score >= 0)
        cout << "VERY_WEAK" << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

* HJ88 扑克牌大小

描述
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如:4 4 4 4-joker JOKER。
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;

(4)输入的两手牌不会出现相等的情况。

输入描述:
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如 4 4 4 4-joker JOKER。

输出描述:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。

代码:

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

int getValue(string& s) {
    if (s == "joker")
        return 14;
    if (s == "JOKER")
        return 15;
    switch (s[0]) {
        case '3':
            return 1;
        case '4':
            return 2;
        case '5':
            return 3;
        case '6':
            return 4;
        case '7':
            return 5;
        case '8':
            return 6;
        case '9':
            return 7;
        case '1':
            return 8; // 用1代替10
        case 'J':
            return 9;
        case 'Q':
            return 10;
        case 'K':
            return 11;
        case 'A':
            return 12;
        case '2':
            return 13;
    }
    return 0;
}

int main() {
    string input;
    getline(cin, input);
    int split_idx = find(input.begin(), input.end(), '-') - input.begin();
    string s1 = input.substr(0, split_idx); // 从'-'处截取成两段
    string s2 = input.substr(split_idx + 1);
    // 如果有王炸直接输出王炸
    if (s1 == "joker JOKER" || s2 == "joker JOKER") {
        cout << "joker JOKER" << endl;
        return 0;
    }
    // 统计字符串中空格的数量
    int space1 = 0, space2 = 0;
    for (char& c : s1)
        if (c == ' ')
            space1++;
    for (char& c : s2)
        if (c == ' ')
            space2++;
    // 输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况
    if (space1 == 3 && space2 == 3) {
        // 都是炸弹
        if (getValue(s1) > getValue(s2)) // 比较炸弹大小
            cout << s1 << endl;
        else
            cout << s2 << endl;
    } else if (space1 == 3) // 字符串其中一个是炸弹,输出炸弹
        cout << s1 << endl;
    else if (space2 == 3)
        cout << s2 << endl;
    else if (space1 == space2) { // 没有炸弹的情况下相同类型才能比较
        if (getValue(s1) > getValue(
                    s2)) // 个子、对子、三个、顺子都是比较第一个大小
            cout << s1 << endl;
        else
            cout << s2 << endl;
    } else // 无法比较
        cout << "ERROR" << endl;

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

* HJ89 24点运算

描述
计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:

3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER

本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。

详细说明:

1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1;
2.牌面210对应的权值为210, J、Q、K、A权值分别为为11、12、13、1;
3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
4.输出的算式格式为4张牌通过±/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;
5.输出算式的运算顺序从左至右,不包含括号,如1+2+3
4的结果为24,2 A 9 A不能变为(2+1)*(9-1)=24
6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0

数据范围:一行由4张牌组成的字符串

输入描述:
输入4张牌为字符串形式,以一个空格隔开,首尾无空格;

输出描述:
输出怎么运算得到24,如果无法得出24,则输出“NONE”表示无解,如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;

代码:

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

unordered_map<string, int> CardtoNum = {{"A", 1}, {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6},
    {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10}, {"J", 11}, {"Q", 12}, {"K", 13}
}; //输入的字符映射到数字
unordered_map<int, string> NumtoCard = {{1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"},
    {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"}, {11, "J"}, {12, "Q"}, {13, "K"}
}; //返回的数字映射到字符
const vector<char> Op = {'+', '-', '*', '/'};

int cal(int a, int b, int op) {
    switch (op) {
        case 0:
            return a + b;
        case 1:
            return a - b;
        case 2:
            return a * b;
        case 3:
            return a / b;
    }
    return 0;
}

bool cal24(vector<int>& a, vector<int>& op) {
    int res = cal(a[0], a[1], op[0]);
    for (int i = 1; i < 3; i++)
        res = cal(res, a[i + 1], op[i]);
    return res == 24;
}

void printFormula(vector<int>& nums, vector<int>& op) {
    for (int i = 0; i < 3; i++)
        cout << NumtoCard[nums[i]] << Op[op[i]];
    cout <<  NumtoCard[nums[3]]  << endl;
}

int main() {
    vector<string> s(4);
    for (int i = 0; i < 4; i++)
        cin >> s[i];

    vector<int> nums(4);
    for (int i = 0; i < 4; i++) {
        if (s[i] == "joker" || s[i] == "JOKER") { // 遇到大小王
            cout << "ERROR" << endl;
            return 0;
        }
        nums[i] = CardtoNum[s[i]]; // 字符串转数字
    }

    sort(nums.begin(), nums.end());
    bool flag = false;
    vector<int> op(4);
    do {
        // 枚举三个符号的所有情况
        for (int i = 0; i < 4 && !flag; i++) {
            op[0] = i;
            for (int j = 0; j < 4 && !flag; j++) {
                op[1] = j;
                for (int k = 0; k < 4 && !flag; k++) {
                    op[2] = k;
                    if (cal24(nums, op)) { // 符合条件
                        printFormula(nums, op);
                        flag = true; // 找到了,准备跳出所有循环
                    }
                }
            }
        }
    } while (next_permutation(nums.begin(), nums.end()) && !flag);

    if (!flag)
        cout << "NONE" << endl;

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

HJ90 合法IP

描述
IPV4地址可以用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此正号不需要出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。

现在需要你用程序来判断IP是否合法。

输入描述:
输入一个ip地址,保证不包含空格

输出描述:
返回判断的结果YES or NO

代码:

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

bool judge_ip(string& s) {
    vector<int> addr;
    stringstream ss(s);
    string seg;
    while (getline(ss, seg, '.')) {
        if (seg.empty())
            return false;
        if (seg.length() > 1 && (!isdigit(seg[0]) || seg[0] == '0'))
            return false;
        addr.push_back(stoi(seg));
    }
    if (addr.size() != 4)
        return false;
    for (int& a : addr)
        if (a < 0 || a > 255)
            return false;
    return true;
}

int main() {
    string ip;
    cin >> ip;
    if (judge_ip(ip))
        cout << "YES" << endl;
    else
        cout << "NO" << endl;

    return 0;
}
// 64 位输出请用 printf("%lld")
  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

UestcXiye

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

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

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

打赏作者

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

抵扣说明:

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

余额充值