华为上机笔试题

扑克牌大小

链接
扑克牌游戏大家应该都比较熟悉了,一副牌由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)输入的两手牌不会出现相等的情况。
参考

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<unordered_set>
#include<set>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<string>
#include<cmath>
  using namespace std;
  class Solution {
  public:
      void methods(string str) {
          int idx = str.find('-');
          string t1 = str.substr(0, idx);
          string t2 = str.substr(idx+1);
          int c1 = count(t1.begin(), t1.end(), ' ');
          int c2 = count(t2.begin(), t2.end(), ' ');
          //排除炸弹和王炸
          if (c1 != c2) {
              if (t1 == "joker JOKER" || t2 == "joker JOKER") {
                  cout << "joker JOKER" << endl;
              }
              else if (c1==3) {
                  cout << t1 << endl;
              }
              else if (c2==3) {
                  cout << t2 << endl;
              }
              else {
                  cout << "ERROR" << endl;
              }
          }
          //除炸弹和王炸之外的
          else {
              //单个的情况最后加一个空格区分
              string s1 = t1 + ' ';
              string s2 = t2 + ' ';
              s1 = s1.substr(0, s1.find(' '));
              s2 = s2.substr(0, s2.find(' '));
              int idx1 = tb.find(s1);
              int idx2 = tb.find(s2);
              if (idx1 > idx2) {
                  cout << t1 << endl;
              }
              else {
                  cout << t2 << endl;
              }
          }
      }
  private:
      string tb = "345678910JQKA2jokerJOKER";
  };
int main() {
   string str;
    Solution sol;
    while(getline(cin,str)){
        sol.methods(str);
    }
}

表示数字

题目描述
将一个字符中所有出现的数字前后加上符号“”,其他字符保持不变
public static String MarkNum(String pInStr)
{
return null;
}
注意:输入数据可能有多行
输入描述:
输入一个字符串
输出描述:
字符中所有出现的数字前后加上符号“
”,其他字符保持不变
示例1
输入
Jkdi234klowe90a3
输出
Jkdi234klowe90a3

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<unordered_set>
#include<set>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<string>
#include<cmath>
  using namespace std;

class Solution {
public:
    void methods(string str) {
        for (int i = 0; i < str.size(); i++) {
            int right=0;
            if (isdigit(str[i])) {
                str.insert(i, "*");
                i++;
            }
            while (isdigit(str[i])) {
                right = i + 1;
                i++;
            }
            if (right) {
                str.insert(right, "*");
            }
        }
        cout << str << endl;
    }
private:
};
  
int main() {
    string str;
    Solution sol;
    while (cin >> str) {
        sol.methods(str);
    }
}

字符串匹配

题目描述
题目标题:
判断短字符串中的所有字符是否在长字符串中全部出现
详细描述:
接口说明
原型:
boolIsAllCharExist(char* pShortString,char* pLongString);
输入参数:
char* pShortString:短字符串
char* pLongString:长字符串
思路:可以首先把长字符串中的每个字符依次放进map里面并且令其值为1,然后对短字符串中每个字符串看看对应的map是不是为1,如果不是直接退出返回false,短字符串中的每个字符对应的map值都为1返回true。算法复杂度为线性。

#include<cstring>
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
class Solution {
  public:
   void methods(string &str1,string &str2){
      map<char,int> mymap;
      for(int i=0;i<str2.size();i++){
        mymap[str2[i]]=1;
      }
      for(int i=0;i<str1.size();i++){
        if(mymap[str1[i]]==1)continue;
        else {
          cout<<"false"<<endl;
          return ;
        }
      }
      cout<<"true"<<endl;
   }
};
int main(){
  string a;
  string b;
  Solution sol;
  while(cin>>a>>b){
    sol.methods(a,b);
  }
}

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

题目描述
样例输出

输出123058789,函数返回值9

输出54761,函数返回值5

接口说明

函数原型:

unsignedint Continumax(char** pOutputstr, char* intputstr)

输入参数:
char* intputstr 输入字符串;

输出参数:
char** pOutputstr: 连续最长的数字串,如果连续最长的数字串的长度为0,应该返回空字符串;如果输入字符串是空,也应该返回空字符串;
返回值:
连续最长的数字串的长度
输入描述:
输入一个字符串。
输出描述:
输出字符串中最长的数字字符串和它的长度。如果有相同长度的串,则要一块儿输出,但是长度还是一串的长度
示例1
输入
abcd12345ed125ss123058789
输出
123058789,9
思路:参考

#include<cstring>
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
using namespace std;
class Solution {
public:
    pair< string ,int> methods(const string & str){
        int n=str.size();
        string res;
        int max=0;
        for(int i=0;i<n;i++){
            if(str[i]<='9' &&str[i]>='0'){
                int begin=i;
                while(i<n &&str[i]>='0' &&str[i]<='9'){
                    i++;
                }
                if(max<i-begin){
                    max=i-begin;
                    res=str.substr(begin,i-begin);
                }
                else if(max==i-begin){
                    res+=str.substr(begin,i-begin);
                }
            }
        }
        return make_pair(res,max);
    }
};
int main()
{
    Solution sol;
    string str;
    while(cin>>str){
        pair<string,int>res=sol.methods(str);
        cout<<res.first<<","<<res.second<<endl;
    }
}

整形数组合并

题目描述
题目标题:
将两个整型数组按照升序合并,并且过滤掉重复数组元素[注: 题目更新了。输出之后有换行]
详细描述:
接口说明
原型:
voidCombineBySort(int* pArray1,intiArray1Num,int* pArray2,intiArray2Num,int* pOutputArray,int* iOutputNum);
输入参数:
int* pArray1 :整型数组1
intiArray1Num:数组1元素个数
int* pArray2 :整型数组2
intiArray2Num:数组2元素个数
输出参数(指针指向的内存区域保证有效):
int* pOutputArray:合并后的数组
int* iOutputNum:合并后数组元素个数
返回值:
void
输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值
输出描述:
输出合并之后的数组
示例1
输入
3
1 2 5
4
-1 0 3 2
输出
-101235

#include<cstring>
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<memory>
using namespace std;
struct Solution {
public:
    void print(set<int> array){
        for(auto p=array.begin();p!=array.end();p++){
            cout<<*p;
        }
        cout<<endl;
    }
};
int main(){
	int n1;
    int n2;
    int temp;
    Solution sol;
    set<int>array;
    while(cin>>n1){
        while(n1--){
            cin>>temp;
            array.insert(temp);
        }
        cin>> n2;
        while(n2--){
            cin>>temp;
            array.insert(temp);
        }
        sol.print(array);
        //记得清除
        array.clear();
    }
}

超长整数相加

题目描述
请设计一个算法完成两个超长正整数的加法。
输入参数:
String addend:加数
String augend:被加数
返回值:加法结果
输入描述:
输入两个字符串数字
输出描述:
输出相加后的结果,string型
示例1
输入
99999999999999999999999999999999999999999999999999
1
输出
100000000000000000000000000000000000000000000000000
思路:参考

#include<cstring>
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<memory>
using namespace std;
struct Solution {
public:
    void print(string str){
        cout<<str<<endl;
    }
    string methods(string & str1,string &str2){
        int temp=0,carry=0;
        while(str1.size()<str2.size()){
            str1="0"+str1;
        }
        while(str1.size()>str2.size()){
            str2="0"+str2;
        }
        for(int i=str1.size()-1;i>=0;i--){
            temp=str1[i]-'0'+str2[i]-'0'+carry;
            str1[i]=temp%10+'0';
            if(temp/10){
                carry=temp/10;
            }
            else{
                carry=0;
            }
        }
        if(carry)str1='1'+str1;
        return str1;
    }
};
int main(){
    string str1;
    string str2;
    Solution sol;
    set<int>array;
    while(cin>>str1>>str2){
        string res=sol.methods(str1,str2);
        sol.print(res);
    }
}

成绩排序

题目描述
查找和排序
题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩
都按先录入排列在前的规则处理。
例示:
jack 70
peter 96
Tom 70
smith 67

从高到低 成绩
peter 96
jack 70
Tom 70
smith 67

从低到高
smith 67
jack 70
Tom 70
peter 96
注:0代表从高到低,1代表从低到高
输入描述:
输入多行,先输入要排序的人的个数,然后分别输入他们的名字和成绩,以一个空格隔开
输出描述:
按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开
示例1
输入
3
0
fang 90
yang 50
ning 70
输出
fang 90
ning 70
yang 50
思路:参考

#include<cstring>
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<memory>
using namespace std;
struct student{
    string name;
    int score;
};
class Solution {
public:
    static bool cmp0(const student &a,const student &b){
        return a.score>b.score;
    } 
    static bool cmp1(const student &a,const student &b){
        return a.score<b.score;
    }
    void methods(vector<student> &stu,int flag){
        if (flag==0){
            stable_sort(stu.begin(),stu.end(),cmp0);
        }
        else{
            stable_sort(stu.begin(),stu.end(),cmp1);
        }
        for(int i=0;i<stu.size();i++){
            cout<<stu[i].name<<" "<<stu[i].score<<endl;
        }
    }
};
int main(){
    Solution sol;
    int n1;
    int n2;
    while(cin>>n1>>n2){
        vector<student> stu(n1);
        for(int i=0;i<n1;i++){
            cin>>stu[i].name>>stu[i].score;
        }
        sol.methods(stu,n2);
    }
}
    

牛牛的背包问题

题目描述
牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
示例1
输入
3 10
1 2 4
输出
8
说明
三种零食总体积小于10,于是每种零食有放入和不放入两种情况,一共有222 = 8种情况。

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<queue>
#include<map>
#include<unordered_map>
#include<cmath>
using namespace std;
long long nums=1;//因为空也算一个
void DFS(vector<long long >& array ,long long w,long long sum,int pos){
    if(sum<=w){
        nums++;
        for(int i=pos+1;i<array.size();i++){
            DFS(array,w,sum+array[i],i);
        }
    }
}
int main(){
    int n;
    long long w;
    while(cin>>n>>w){
        long long total=0;
        vector<long long> array(n,0);
        for(int i=0;i<n;i++){
            cin>>array[i];
            total+=array[i];
        }
        if(total<=w){
            nums=pow(2,n);
        }
        else{
            sort(array.begin(),array.end());
            for(int i=0;i<n;i++){
                DFS(array,w,array[i],i);
            }
        }
        cout<<nums<<endl;
    }
}

小明的字符串

题目描述
小明同学需要对一个长度为 N 的字符串进行处理,他需要按照要求执行若干步骤,每个步骤都均为下面 2 种操作中的一种,2 种操作如下:
TYPE 1. 从字符串结尾开始算起,将第 X 个字符之前的字符移动到字符串末尾
TYPE 2. 输出字符串索引为 X 的字符
小明尝试了很久没能完成,你可以帮他解决这个问题吗?
输入描述:
第一行,包含两个整数,字符串的长度 N 和操作次数T;
第二行为要操作的原始字符串;
之后每行都是要执行的操作类型 TYPE 和操作中 X 的值,均为整数。
输入范围:
字符串长度 N:1 <= N <= 10000
操作次数 T:1 <= T <= 10000
操作类型 TYPE:1 <= TYPE<= 2
变量 X:0 <= X < N
输出描述:
操作的执行结果
示例1
输入
6 2
xiaomi
1 2
2 0
输出
m
思路:参考

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<queue>
#include<map>
#include<unordered_map>
#include<cmath>
using namespace std;
struct Solution{
    public:

        void methods(string & str,int type,int x ){
            if(type==1){
                str=str.substr(str.size()-x)+str.substr(0,str.size()-x);
            }
            else{
                cout<<str[x]<<endl;
            }
            
        }
    private:
        
};
int main(){
    Solution sol;
    int n,t;
    while(cin>>n>>t){
        string str;
        string res;
        cin>>str;
        for(int i=0;i<t;i++){
            int type,x;
            cin>>type>>x;
            sol.methods(str,type,x);
        }
    }
}

小招喵跑步

小招喵喜欢在数轴上跑来跑去,假设它现在站在点n处,它只会3种走法,分别是:
1.数轴上向前走一步,即n=n+1
2.数轴上向后走一步,即n=n-1
3.数轴上使劲跳跃到当前点的两倍,即n=2*n
现在小招喵在原点,即n=0,它想去点x处,快帮小招喵算算最快的走法需要多少步?
输入描述:
小招喵想去的位置x
输出描述:
小招喵最少需要的步数
示例1
输入
3
输出
3

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<list>
#include<memory>
#include<map>
#include<queue>
#include<sys/types.h>
#include<unistd.h>
using namespace std;
struct Solution{
    public:
        void methods(int x){
            x=abs(x);
            vector<int> dp(x+1,0);
            dp[1]=1;
            dp[2]=2;
            dp[3]=3;
            for(int i=4;i<=x;i++){
                if(i%2==0){
                    dp[i]=min(dp[i-1],dp[i/2])+1;
                }
                else{
                    dp[i]=min(dp[i-1],dp[(i+1)/2]+1)+1;
                }
            }
            cout<<dp[x]<<endl;
        }
};
int main(){
    Solution sol;
    int x;
    while(cin>>x){
        sol.methods(x);
    }
}

超链接

在这里插入图片描述

示例1
输入
5
sina
qq
taobao
jd
baidu
3
qq
baidu
baidu
输出
jd
sina
taobao
在这里插入图片描述

#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<list>
#include<memory>
#include<map>
#include<queue>
#include<set>
#include<unordered_map>
#include<list>
#include<stack>
#include<iomanip>
using namespace std;
struct Solution
{
    public:
        vector<string> methods(vector<string > & str1,vector<string> &str2){
            map<string,int> mymap;
            for(int i=0;i<str1.size();i++){
                mymap[str1[i]]++;
            }
            for(int i=0;i<str2.size();i++){
                mymap[str2[i]]--;
            }
            vector<string> res;
            for(auto it=mymap.begin();it!=mymap.end();it++){
                if(it->second==1){
                    res.push_back(it->first);
                }
            }
            return res;
        }
    private:
};

int main(){
    Solution sol;
    int n,n1;
    while(cin>>n){
        vector<string> str1(n);
        for(int i=0;i<str1.size();i++){
            cin>>str1[i];
        }
        while(cin>>n1){
            vector<string>str2(n1);
            for(int i=0;i<n1;i++){
                cin>>str2[i];
            }
            vector<string> res=sol.methods(str1,str2);
            for(int i=0;i<res.size();i++){
                cout<<res[i]<<endl;
            }
        }
    }
    // vector<string> str1={"sina","qq","taobao","jd","baidu"};
    // vector<string> str2={"qq","baidu","baidu"};
    // sol.methods(str1,str2);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值