华为机试ACM部分笔记---C++

一,HJ1 字符串最后一个单词的长度

描述

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

输入描述:

输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:

输出一个整数,表示输入字符串最后一个单词的长度。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
#define ARR_MAX (5000)

int main() {
    char s [ARR_MAX + 1] = {0};
    int i = 0;
    int len = 0;
    while(cin >> s) {
        len = strlen(s);
    }
    cout << len;
}
// 64 位输出请用 printf("%lld")

二,HJ2 计算某字符出现次数

描述

写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)

数据范围:  1≤n≤1000 

输入描述:

第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)。

输出描述:

输出输入字符串中含有该字符的个数。(不区分大小写字母)

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

int main() {
    char a[1003] = {0};
    char b[3] = {0};
    int i = 0, len = 0;
    int count = 0;

    while (cin.getline(a,1002)) { // 注意 while 处理多个 case
        cin.getline(b, 2);
        len = strlen(a);
        if (0 == len) return 0;
        for(; i < len; i ++){
           if (tolower(b[0]) == tolower(a[i])) {
            count++;
           }
        }
        cout << count << endl;
    }
}
// 64 位输出请用 printf("%lld")

注意:

1,cin.getline()会算上后面的换行。

2,记住函数

tolower(),toupper(), #include <algorithm>  transform(begin, end, begin,::toupper) 

三,HJ3 明明的随机数

描述

明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。

数据范围: 1≤n≤1000  ,输入的数字大小满足  1≤val≤500 

输入描述:

第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。

输出描述:

输出多行,表示输入数据处理后的结果

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

int main() {
    int count = 0;
    int i;
    short data;
    bool is_dup;
    vector<short> nums;
    while (cin >> count) { // 注意 while 处理多个 case
        if((count > 1000) || (count <= 0)) return 0;
        for(i = 0; i < count; i++){
            cin >> data;
            for(short num : nums) {
                if (num == data) {
                    is_dup = true;
                    break;
                }
            }
            if(!is_dup)
            nums.push_back(data);
            is_dup = false;
        }
        sort(nums.begin(), nums.end());
        //sort(nums.rbegin(), nums.rend()); 反向排序
    }
    for(short num : nums) {
       cout << num << endl;
    }
}
// 64 位输出请用 printf("%lld")

这里使用到了vector,  #include<algorithm>的sort()函数。

四,HJ4 字符串分隔

描述

•输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;

•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。

输入描述:

连续输入字符串(每个字符串长度小于等于100)

输出描述:

依次输出所有分割后的长度为8的新字符串

#include <iostream>
using namespace std;

int main() {
    string str;
    int i = 0, len = 0;
    char zeros[] = {'0','0','0','0','0','0','0','\0'};
    while (cin >> str ) { // 注意 while 处理多个 case
        len = str.length();
        for (i = 0; i < len - 8; i +=8 ) {
            cout << str.substr(i, 8) << endl;
        }
        cout << str.substr(i) << &(zeros[len - i - 1]) << endl;
    }
}
// 64 位输出请用 printf("%lld")

这里使用了str.substr()函数。其中两个参数的,第二个参数是字串的长度。 

五,HJ5 进制转换

描述

写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

数据范围:保证结果在  1≤n≤231−1 

输入描述:

输入一个十六进制的数值字符串。

输出描述:

输出该数值的十进制字符串。不同组的测试用例用\n隔开。

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

int main() {
    string num_str;
    int decimalValue;

    while (cin >> num_str) { // 注意 while 处理多个 case
        decimalValue = stoi(num_str, nullptr, 16);
        cout << decimalValue << endl;
    }
}

尽量用标准库函数stoi()

 六,HJ6 质数因子

描述

功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )

数据范围:  1≤n≤2×109+14 

输入描述:

输入一个整数

输出描述:

按照从小到大的顺序输出它的所有质数的因子,以空格隔开。

#include <iostream>
using namespace std;

int main() {
    int num;
    int x = 2;
    int temp;

    while (cin >> num) { // 注意 while 处理多个 case
        temp = num;
        for ( x = 2; (x * x) <= temp; ) {
            if (0 == (temp % x)) {
              cout << x << ' ';
              temp /= x;
              continue;
            }
            x ++;
        }
    }
    cout << temp << endl;
    return 0;
}
// 64 位输出请用 printf("%lld")

 这题主要是要考虑,for循环中,判断条件是质数的平方小于这个数。否则会报超时。

七,HJ7 取近似值 

描述

写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。

#include <iostream>
using namespace std;

int getInt(float in) {
    return int (in + 0.5);
}

int main() {
    float a;
    while (cin >> a) { // 注意 while 处理多个 case
        cout << getInt(a) << endl;
    }
}

八,合并表记录 

描述

数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。

提示:

0 <= index <= 11111111

1 <= value <= 100000

输入描述:

先输入键值对的个数n(1 <= n <= 500)
接下来n行每行输入成对的index和value值,以空格隔开

输出描述:

输出合并后的键值对(多行)

#include<iostream>
#include<map>
using namespace std;
 
int main() {
    int n, key, value;
    map<int, int> nums;
    while (cin >> n) {
        while (n--) {
            cin>>key>>value;
            if (!nums[key]) {
                nums[key] = value;
            } else {
                nums[key] += value;
            }
        }
        //for (map<int,int>::iterator it = nums.begin(); it != nums.end(); it++) 
        //    cout << it->first << " " << it->second << endl;
        for (auto & num : nums) {
            cout << num.first << " " << num.second << endl;
        }
    }
    return 0;
}

这题主要是使用map。使用其他的要写一大堆。 

九,HJ9 提取不重复的整数

描述

输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

保证输入的整数最后一位不是 0 。

数据范围: 1≤n≤108 

输入描述:

输入一个int型整数

输出描述:

按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

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

int main() {
    char data[30] = {0};
    char out[30] = {0};

    while (cin >> data ) { // 注意 while 处理多个 case
        for (int i = strlen(data) - 1; i >= 0 ; i --) {
            bool find_dup = false;
            for (int j = 0; j <= strlen(out) ; j ++) {
                if(data[i] == out[j]){
                    find_dup = true;
                    break;
                }
            }
            if(find_dup) continue;
            else out[strlen(out)] = data[i];
        }
        int len = strlen(out);
        for (int i = 0; i < len; i ++){
            cout << out[i];
        }
    
        cout << endl;
    }

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

 cin的类型可以是int,也可以是string。

十,HJ13 句子逆序

描述

将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”

所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符

数据范围:输入的字符串长度满足 1≤n≤1000 

注意本题有多组输入

输入描述:

输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

输出描述:

得到逆序的句子

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

int main() {
    char a[1500] = {0};
    vector<char*> vec;
    char* p  = a;
    while (cin >> p) { // 注意 while 处理多个 case
        vec.push_back(p);
        p += strlen(p) + 1;
    }

    for (int i = vec.size() - 1 ; i >= 0 ; i --) {
        cout << vec[i];
        if(i > 0) cout << ' ';
    }
    cout << endl;
}

十一, HJ14 字符串排序

描述

给定 n 个字符串,请对 n 个字符串按照字典序排列。

数据范围:  1≤n≤1000  ,字符串长度满足  1≤len≤100 

输入描述:

输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。

输出描述:

数据输出n行,输出结果为按照字典序排列的字符串。

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

int main() {
    int num;
    vector<string> vec;
    while (cin >> num) { // 注意 while 处理多个 case
        string s;
        while(cin >> s) {
            vec.push_back(s);
        }
    }
    sort(vec.begin(), vec.end());
    for (string ss : vec) {
        cout << ss << endl;
    }
}
// 64 位输出请用 printf("%lld")

这题需要 #include "algorithm",用 sort(vec.begin(), vec.end()); 否则写要累死人了。

十二,HJ15 求int型正整数在内存中存储时1的个数

描述

输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。

数据范围:保证在 32 位整型数字范围内

输入描述:

 输入一个整数(int类型)

输出描述:

 这个数转换成2进制后,输出1的个数

#include <iostream>
using namespace std;

int main() {
    int num;
    int count = 0;
    while (cin >> num ) { // 注意 while 处理多个 case
        while(num) {
            num = num & (num-1);
            count ++;
        }
        cout << count << endl;
    }
}

十三,HJ17 坐标移动

描述

开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。

输入:

合法坐标为A(或者D或者W或者S) + 数字(两位以内)

坐标之间以;分隔。

非法坐标点需要进行丢弃。如AA10;  A1A;  $%$;  YAD; 等。

下面是一个简单的例子 如:

A10;S20;W10;D30;X;A1A;B10A11;;A10;

处理过程:

起点(0,0)

+   A10   =  (-10,0)

+   S20   =  (-10,-20)

+   W10  =  (-10,-10)

+   D30  =  (20,-10)

+   x    =  无效

+   A1A   =  无效

+   B10A11   =  无效

+  一个空 不影响

+   A10  =  (10,-10)

结果 (10, -10)

数据范围:每组输入的字符串长度满足  1≤n≤10000  ,坐标保证满足  −231≤x,y≤231−1  ,且数字部分仅含正数

输入描述:

一行字符串

输出描述:

最终坐标,以逗号分隔

示例1

输入:

A10;S20;W10;D30;X;A1A;B10A11;;A10;

复制输出:

10,-10

复制

示例2

输入:

ABC;AKL;DA1;

复制输出:

0,0
#include <iostream>
#include <string>
#include <cstring>
using namespace std;


bool isValid (char s) {
    return ('A' == s)||('S' == s)||('D' == s)||('W' == s);
}

 bool AllisNum(string str) {  
    for (int i = 0; i < str.size(); i++) {
        int tmp = (int)str[i];
        if (tmp >= 48 && tmp <= 57) {
            continue;
        } else {
            return false;
        }
     } 
     return true;
} 

int moveOnce(string input, int* const outX, int* const outY) {
    int i = 1;
    int count = 0;
    int x = 0, y = 0;

    while(input[i] != ';')i ++;

    if (i > 1 && isValid(input[0])) {
        string numStr = input.substr(1, i - 1);
        if (!AllisNum(numStr)) return i;
        count = stoi(numStr);
        if('A' == input[0]) {x-= count;}
        else if('D' == input[0]) {x += count;}
        else if('W' == input[0]) {y += count;}
        else if('S' == input[0]) {y -= count;}
        *outX += x;
        *outY += y;
    }
    return i;
}

int main() {
    string input;
    string cursor;
    while (cin >> input) { // 注意 while 处理多个 case
        int dec_len;
        int x = 0, y = 0;
        cursor = input;
        do {
           dec_len = moveOnce(cursor, &x, &y);
           if (cursor.length()  - 3 < dec_len) break;
           while (cursor[dec_len ] == ';'){
               dec_len ++;
           }
           cursor = cursor.substr(dec_len, cursor.length());
        } while( cursor.length() > 0); 
        cout << x <<','<< y << endl;
    }
}
// 64 位输出请用 printf("%lld")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值