华为OD机试C卷编程题题解汇总(持续更新)

目录

1、用连续自然数之和来表达整数

2、题目描述:密码输入检测

3、找出作弊的人

4、找座位

5、求满足条件的最长子串的长度

6、万能单词拼写

7、内存冷热标记

8、学生排名_智能成绩表

9、最多购买宝石数目  

10、构成指定长度字符串的个数

11、幸存数之和

12、高矮个子排队

13、关联子串

14、求满足条件的最长子串的长度

16、中庸行者

17、小华地图寻宝

18、跳马问题 dfs/bfs

19、园区参观路径 dfs/bfs

20、5G网络建设

21、计算三叉搜索树的高度

22、石头剪刀布游戏

23、分配土地

24、王者荣耀比赛

25、执行任务赚积分

26、机器人搬砖

27、分披萨

 C++语法重点


1、用连续自然数之和来表达整数

 一个整数可以由连续的自然数之和来表示。

给定一个整数,计算该整数有几种连续自然数之和的表达式,且打印出每种表达式

输入描述

一个目标整数T (1 <=T<= 1000)

输出描述

该整数的所有表达式和表达式的个数。如果有多种表达式,输出要求为:

自然数个数最少的表达式优先输出

每个表达式中按自然数递增的顺序输出,具体的格式参见样例。

在每个测试数据结束时,输出一行”Result:X”,其中X是最终的表达式个数。

#include <iostream>
#include <ostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
bool cmp_length(const string s1, const string s2){
    return s1.length() < s2.length();
}
void find_sum(const int tar, vector<string>& exp){
    for(int i = 1; i <= tar; i++){
        int sum_i = 0;
        cout << "i = " << i << endl;
        string expresion_i = to_string(tar) + "=";
        for(int j = i; j <= tar; j++){//sum_i < target
            sum_i += j;
            expresion_i += to_string(j) + "+";
            if(tar == sum_i){
                expresion_i = expresion_i.substr(0, expresion_i.length() - 1);
                exp.push_back(expresion_i);
                cout << expresion_i << endl;
                break;
            }
        }
    }
}

int main(){
    cout << "input target =" << endl;
    int target;
    cin >> target;
    cout << "target = " << target << endl;
    vector<string> expression;
    find_sum(target, expression);
    cout << "vector_size = " << expression.size() << endl;
    sort(expression.begin(), expression.end(), cmp_length);
    for(auto exp : expression){//exp&
        cout << exp;
        cout << endl;
    }
    cout << endl;
    return 0;
}

传容器要传引用

sort要传新函数名

string可以用+

substr(pos,从pos开始拷贝n个)

容器名.pushback()往容器放东西

打印容器for(auto vector : vectors){cout << vector};

2、题目描述:密码输入检测

给定用户密码输入流input,输入流中字符’<'表示退格,可以清除前一个输入的字符,请你编写程序,输出最终得到的密码字符,并判断密码是否满足如下

安全要求。

密码安全要求如下:

1.密码长度>=8;

2.密码至少需要包含1个大写字母;

3.密码至少需要包含1个小写字母;

4.密码至少需要包含1个数字;

5.密码至少需要包含1个字母和数字以外的非空白特殊字符

注意空串退格后仍然为空串,且用户输入的字符串不包含‘<’字符和空白字符。

输入描述

用一行字符串表示输入的用户数据,输入的字符串中‘<’字符标识退格,用户输入的字符串不包含空白字符,例如: ABC<c89%000<

输出描述

输出经过程序处理后,输出的实际密码字符串,并输出改密码字符串是否满足密码安全要求。两者间由‘,’分隔, 例如: ABc89%00,true

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



int main(){
    cout << "input origin string =" << endl;
    string origin_string;
    cin >> origin_string;
    cout << "origin string = " << origin_string << endl;
    
    bool bigger_eight = false, include_big= false, include_small= false, include_number= false, include_strange= false;
    
    vector<char> last_array;
    for(auto char_in : origin_string){
        if ('<' == char_in){
            if(!last_array.empty()){
                last_array.pop_back();
            }
        }
        else{
            last_array.push_back(char_in);
            cout << "char_in =" << char_in << endl;
            if((char_in >= 'A') && (char_in <= 'Z')){
                include_big = true;
            }
            else if((char_in >= 'a') && (char_in <= 'z')){
                include_small = true;
            }
            else if((char_in >= '0') && (char_in <= '9')){
                include_number = true;
            }
            else{
                include_strange = true;
            }
                
        }
    }
    if (last_array.size() >= 8){
        bigger_eight = true;
    }
    
    cout << "last string = " << endl;
    for (auto char_in_string : last_array){
        cout << char_in_string;
    }
    cout << "," ;
    
    cout << "every result=" << bigger_eight<<include_big<<include_small<<include_number<<include_strange<<endl;
    if (bigger_eight&&include_big&&include_small&&include_number&&include_strange)
        cout << "true";
    else
        cout << "false";
    cout << endl;
    return 0;
}

string.length()  vector.size() 别弄混了

vector.push_back() vector.pop_back(char) vector.empty() 不需要求长度

特殊字符的bool值在每种情况都被改了!导致include_strange是最后一个字符的结果

3、找出作弊的人

题目描述

公司组织了一次考试,现在考试结果出来了,想看一下有没人存在作弊行为,但是员工太多了,需要先对员工进行一次过滤,

再进一步确定是否存在作弊行为。

过滤的规则为:找到分差最小的员工ID对(p1,p2)列表,要求p1<p2

员工个数取值范国:O<n<100000

员工ID为整数,取值范围:0<=n<=100000

考试成绩为整数,取值范围:0<=score<=300

输入描述

员工的ID及考试分数

输出描述

分差最小的员工ID对(p1,p2)列表,要求p1<p2。每一行代表一个集合,每个集合内的员工ID按顺序排列,多行结果也以员工

对中p1值大小升序排列(如果p1相同则p2升序)。

vector<pair<int, int>> employee;
cin >> employee[i].first >> employee[i].second;
cmp_pair(pair<int, int> a, pair<int, int> b){
    a.second < b.second
}

pair的使用如上

C++ vector中使用pair 及 pair的基本用法总结(转) - 简书 (jianshu.com)

4、找座位

题目描述

在一个大型体育场内举办了一场大型活动,由于疫情防控的需要,要求每位观众的必须间隔至少一个空位才允许落座。

现在给出一排观众座位分布图,座位中存在已落座的观众,请计算出,在不移动现有观众座位的情况下,最多还能坐下多少名观众。

输入描述

一个数组,用来标识某一排座位中,每个座位是否已经坐人。0表示该座位没有坐人,1表示该座位已经坐人。

1 ≤ 数组长度 ≤ 10000

输出描述

整数,在不移动现有观众座位的情况下,最多还能坐下多少名观众。

用例1

输入

10001

输出

1

用例2

输入

0101

输出

0

#include <iostream>
#include <string>
using namespace std;
int main() {
 string input;//string可以直接用数组角标
 cin >> input; // 读取输入的座位信息
 int maxAdditional = 0; // 最大额外观众数初始化为0
 for (int i = 0; i < input.length(); i++) { // 遍历座位数组
 if (input[i] == '0' && (i == 0 || input[i - 1] == '0') && (i == input.length() - 1 || input[i + 1] == '0')) {
 // 如果当前位置是空座且左侧或右侧也是空座,执行以下操作,不需要前后加0,直接特殊情况加条件上即可
 maxAdditional++; // 最大额外观众数加1
 input[i] = '1'; // 将当前位置标记为已坐人,避免了多个000的情况
 i++; // 跳过下一个位置,因为已经坐人
 }
 }
 cout << maxAdditional << endl; // 打印最大额外观众数
 return 0;
}

string[]的用法

特殊情况简化为判断条件

5、求满足条件的最长子串的长度

重看,有空自己重写

题目描述

给定一个字符串,只包含字母和数字,按要求找出字符串中的最长(连续)子串的长度,字符串本身是其最长的子

串,子串要求:

1、 只包含1个字母(a~z, A~Z),其余必须是数字;

2、 字母可以在子串中的任意位置;

如果找不到满足要求的子串,如全是字母或全是数字,则返回-1。

输入描述

字符串(只包含字母和数字)

输出描述

子串的长度

判断是否是字母(isalpha(c))

顺序遍历,查找子串使用queue

#include <iostream>
#include <deque>
#include <string>
using namespace std;
int main() {
 // 读取输入的字符串
 string str;
 cin >> str;
 // 初始化最长子串长度为-1
 int maxLen = -1;
 // 初始化一个标志,表示是否找到了包含字母的子串
 bool hasLetter = false;
 // 初始化双指针l和r,分别表示子串的左右边界
 int l = 0, r = 0;
 // 创建一个双端队列用于存储字母的索引
 deque<int> letterIdx;
 // 遍历字符串
 while (r < str.length()) {
 // 获取当前字符
 char c = str[r];
 // 如果当前字符是字母
 if (isalpha(c)) {
 // 设置标志为true,表示找到了包含字母的子串
 hasLetter = true;
 // 将字母的索引添加到队列的尾部
 letterIdx.push_back(r);
 // 如果队列中有多于1个字母的索引
 if (letterIdx.size() > 1) {
 // 移除队列头部的字母索引,并将左指针l移动到该索引的下一个位置
 l = letterIdx.front() + 1;
 letterIdx.pop_front();
 }
 // 如果右指针r等于左指针l,跳过当前循环
 if (r == l) {
 r++;
 continue;
 }
 }
 // 更新最长子串长度
 maxLen = max(maxLen, r - l + 1);
 // 移动右指针
 r++;
 }
 // 如果没有找到包含字母的子串,输出-1
 if (!hasLetter) {
 cout << -1 << endl;
 } else {
 // 否则输出最长子串长度
 cout << maxLen << endl;
 }
 return 0;
}
6、万能单词拼写

题目描述

有一个字符串数组 words 和一个字符串 chars。假如可以用 chars 中的字母拼写出 words 中的某个“单词”(字符串),那么我们就认为你掌握了这个单词。

words 的字符仅由 a-z 英文小写字母组成,例如 “abc”

chars 由 a-z 英文小写字母和 “?” 组成。其中英文 “?” 表示万能字符,能够在拼写时当作任意一个英文字母。例如:“?” 可以当作 “a” 等字母。

注意:每次拼写时,chars 中的每个字母和万能字符都只能使用一次。

输出词汇表 words 中你掌握的所有单词的个数。没有掌握任何单词,则输出0。

输入描述

第一行:输入数组 words 的个数,记作N。

第二行 ~ 第N+1行:依次输入数组words的每个字符串元素

第N+2行:输入字符串chars

输出描述

输出一个整数,表示词汇表 words 中你掌握的单词个数

备注

1 ≤ words.length ≤ 100

1 ≤ words[i].length, chars.length ≤ 100

所有字符串中都仅包含小写英文字母、英文问号

统计chars每个字符的数量和?数量。

统计words每个字符数量。求出words比chars多的字符数量(每次求出差值就用问号数量去减,减到小于0就无法拼写),如果小于?数量,则无法拼写。

#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 判断是否可以拼写单词
bool canSpell(vector<int>& wordCount, vector<int>& count, int wildcards) {
 for (int i = 0; i < 26; i++) {
 if (wordCount[i] > count[i]) {
 wildcards -= wordCount[i] - count[i]; // 如果单词中的字母数量大于字符集中的字母数量,则使用问号替代
 if (wildcards < 0) {
 return false; // 如果问号不足,则返回false
 }
 }
 }
 return true; // 如果所有的字母都可以匹配,则返回true
}
int main() {
 int N;
 cin >> N; // 读取单词数量
 cin.ignore(); // 忽略换行符
 vector<string> words(N);
 for (int i = 0; i < N; i++) {
 getline(cin, words[i]); // 读取每个单词
 }
 string chars;
 getline(cin, chars); // 读取字符集
 vector<int
  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值