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

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

  • 华为机试真题练习汇总(81~90)
    • [HJ81 字符串字符匹配](#HJ81 字符串字符匹配)
    • [** HJ82 将真分数分解为埃及分数](#** HJ82 将真分数分解为埃及分数)
    • [HJ83 二维数组操作](#HJ83 二维数组操作)
    • [HJ84 统计大写字母个数](#HJ84 统计大写字母个数)
    • [HJ85 最长回文子串](#HJ85 最长回文子串)
    • [HJ86 求最大连续bit数](#HJ86 求最大连续bit数)
    • [HJ87 密码强度等级](#HJ87 密码强度等级)
    • [* HJ88 扑克牌大小](#* HJ88 扑克牌大小)
    • [* HJ89 24点运算](#* HJ89 24点运算)
    • [HJ90 合法IP](#HJ90 合法IP)

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

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

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

HJ81 字符串字符匹配

描述

判断短字符串S中的所有字符是否在长字符串T中全部出现。

请注意本题有多组样例输入。

输入描述:

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

输出描述:

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

代码:

cpp 复制代码
#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

代码:

cpp 复制代码
#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 输出查询单元格数据是否成功

代码:

cpp 复制代码
#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')的个数。

字符串中可能包含空格或其他字符。

输入描述:

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

输出描述:

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

代码:

cpp 复制代码
#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 最长回文子串

描述

给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。

所谓回文串,指左右对称的字符串。

所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串

输入描述:

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

输出描述:

返回最长回文子串的长度

代码:

cpp 复制代码
#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:

cpp 复制代码
#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:

cpp 复制代码
#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的密码 **输出描述:** 输出密码等级 代码: ```cpp #include #include #include 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。 代码: ```cpp #include #include 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.牌面2~10对应的权值为2~10, 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",表示无法运算; 代码: ```cpp #include #include #include #include using namespace std; unordered_map 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 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 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& a, vector& 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& nums, vector& op) { for (int i = 0; i < 3; i++) cout << NumtoCard[nums[i]] << Op[op[i]]; cout << NumtoCard[nums[3]] << endl; } int main() { vector s(4); for (int i = 0; i < 4; i++) cin >> s[i]; vector 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 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 代码: ```cpp #include #include #include #include using namespace std; bool judge_ip(string& s) { vector 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") ```

相关推荐
四谷夕雨34 分钟前
C++八股——智能指针
c++
Once_day1 小时前
C++之fmt库介绍和使用(1)
开发语言·c++·fmt
是店小二呀1 小时前
【优选算法 | 字符串】字符串模拟题精选:思维+实现解析
android·c++·算法
不爱学英文的码字机器1 小时前
[操作系统] 策略模式进行日志模块设计
c++·策略模式
凤年徐2 小时前
【C/C++】自定义类型:结构体
c语言·开发语言·c++·经验分享·笔记·算法
DARLING Zero two♡2 小时前
C++效率掌握之STL库:map && set底层剖析及迭代器万字详解
c++·stl·set·map
绯樱殇雪2 小时前
编程题 02-线性结构3 Reversing Linked List【PAT】
c++·pat考试
Rachelhi3 小时前
C++.神经网络与深度学习(赶工版)(会二次修改)
c++·深度学习·神经网络
理论最高的吻3 小时前
77. 组合【 力扣(LeetCode) 】
c++·算法·leetcode·深度优先·剪枝·回溯法
zyx没烦恼3 小时前
unordered_map和unordered的介绍和使用
开发语言·c++