华为上机题汇总(十二)

时间:2022-01-17 18:52:57

华为上机题汇总(十二)

注:编译环境为Visual Studio 2012,答案仅供参考。

目录

第五十六题

56.在中国,形容夫妻恩爱的词汇中,大家用的比较多的就是“夫妻相”。所谓“夫妻相”,就是两个人看上去比较般配,长相、身材等某些方面有一定的相似度。本题则另辟蹊径,从人的姓名维度,以字母重复个数来寻找最具“夫妻相”的人。
题目中预先给定一组女士的姓名拼音。输入男士的姓名拼音(拼音中间可以有空格,字母全部小写),依预先给定姓名拼音的先后遍历所有姓名,输出字母重复数最多的女士姓名。
规则:如果字母重复数最多的女士有多位相同,则以最先匹配的女士做为最具“夫妻相”的人选。
规则:人名中的相同字母,按重复一次处理。例如:li ling 与li lei 重复的字符个数为2,而不是4。
预置女士名单(先后循序必须保证):
“wang fei”,
“zhang man yu”,
“zhang zhi yi”,
“li li”,
“li xiao man”,
“li yu cun”,
“yang ni”,
“xiao tong”,
“li lei”,
“zhang san”
运行时间限制: 无限制
内存限制: 无限制
输入: 输入一个男士姓名,字符串
输出: 输出最具“夫妻相”的女士姓名

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

string s[] = {"wang fei","zhang man yu","zhang zhi yi","li li","li xiao man","li yu cun","yang ni","xiao tong","li lei","zhang san"};

string dealStr(const string &str){
    string result;
    bool chars[26];
    for (int i = 0; i < 26; i++)
    {
        chars[i] = false;
    }
    for (unsigned i = 0; i < str.size(); i++)
    {
        if (str[i] >= 'a' && str[i] <= 'z' && !chars[str[i] - 'a'])
        {
            chars[str[i] - 'a'] = true;
            result.push_back(str[i]);
        }
    }
    sort(result.begin(),result.end());
    return result;
}

int countSum(const string &s1, const string &s2){
    auto b1 = s1.begin(), b2 = s2.begin();
    int sum = 0;
    while (b1!= s1.end() && b2 != s2.end())
    {
        if (*b1 == *b2)
        {
            b1++;
            b2++;
            sum++;
        }
        else if (*b1 < *b2)
        {
            b1++;
        }
        else
        {
            b2++;
        }
    }
    return sum;
}

string match(const string &male){
    string female = s[0], maleStr = dealStr(male);
    int max = countSum(maleStr,dealStr(female));
    for (int i = 1; i < 10; i++)
    {
        int sum = countSum(maleStr,dealStr(s[i]));
        if (sum > max)
        {
            female = s[i];
            max = sum;
        }
    }
    return female;
}

int main()
{
    string s;
    cout << "请输入待测男士的拼音:";
    getline(cin,s);
    cout << match(s) << endl;
    return 0;
}

第五十七题

57.CandyBrush游戏
描述: CandyBrush一款流行的消除游戏,在一个方阵中布满各种糖果,任意交换两个糖果,如果交换后出现横向或者竖向有连续三个相同的情况,则可以消除糖果并得分。
输入个字符组成的字符串(编号为到),表示×的方阵,每个字符表示不同类型的糖果(区分大小写),判断是否有解,即交换某两个糖果后能够消除糖果。
举例,下面的方阵无解
T M T M O
X R U C q
A B C X R
U R M T O
T Q C R A
下面的方阵交换(0, 2)和(1, 2)两个糖果后,能消除M
T M T M O
X R M C q
A B C X R
U R M T O
T Q C R A
如果有解,则输出YES,同时输出所有交换方案中,被交换糖果最小编号(到),比如:上面的方阵中,被交换的糖果,编号最小的为糖果“T”,编号为。
如果无解,则输出NO。
运行时间限制: 无限制
内存限制: 无限制
输入:
输入个字符组成的字符串,不含空格,表示×的方阵
输出:
如果有解,则输出YES,同时输出所有交换方案中,被交换糖果最小编号,以空格隔开。如果无解,则输出NO。

样例输入:
TMTMOXRMCqABCXRURMTOTQCRA
样例输出:
YES 3
答案提示:
输出最小糖果编号的意思,就是从左至右,从上到下遍历糖果,找到第一个跟其他交换后能消除的糖果即可。

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

bool canAdd(int index, const vector<int> &answers){
    for (unsigned i = 0; i < answers.size(); i++)
    {
        if (index == answers[i])
        {
            return false;
        }
    }
    return true;
}

bool hasThreeSame(int row, int col, int n ,const vector<string> &v){
    for (int i = row-2; i <= row; i++)
    {
        if (i < 0) continue;
        if (i >= n - 2) break;
        if (v[i][col] == v[i+1][col] && v[i][col] == v[i+2][col])
        {
            return true;
        }
    }

    for (int i = col-2; i <= col; i++)
    {
        if (i < 0) continue;
        if (i >= n - 2) break;
        if (v[row][i] == v[row][i+1] && v[row][i] == v[row][i+2])
        {
            return true;
        }
    }
    return false;
}

void canMove(int row, int col, int n, const vector<string> &v, vector<int> &answers){

    if (row > 0)
    {
        vector<string> tmpV = v;
        char tmp = tmpV[row][col];
        tmpV[row][col] = tmpV[row-1][col];
        tmpV[row-1][col] = tmp;

        if (hasThreeSame(row,col,n,tmpV)){
            int index = (row-1)*n+col;
            if (canAdd(index,answers))
            {
                answers.push_back(index);
            }
        }
    }
    if (row < n-1)
    {
        vector<string> tmpV = v;
        char tmp = tmpV[row][col];
        tmpV[row][col] = tmpV[row+1][col];
        tmpV[row+1][col] = tmp;

        if (hasThreeSame(row,col,n,tmpV)){
            int index = row*n+col;
            if (canAdd(index,answers))
            {
                answers.push_back(index);
            }
        }
    }
    if (col > 0)
    {
        vector<string> tmpV = v;
        char tmp = tmpV[row][col];
        tmpV[row][col] = tmpV[row][col-1];
        tmpV[row][col-1] = tmp;

        if (hasThreeSame(row,col,n,tmpV)){
            int index = row*n+col-1;
            if (canAdd(index,answers))
            {
                answers.push_back(index);
            }
        }
    }
    if (col < n-1)
    {
        vector<string> tmpV = v;
        char tmp = tmpV[row][col];
        tmpV[row][col] = tmpV[row][col+1];
        tmpV[row][col+1] = tmp;

        if (hasThreeSame(row,col,n,tmpV)){
            int index = row*n+col;
            if (canAdd(index,answers))
            {
                answers.push_back(index);
            }
        }
    }
}

bool game(int n, const vector<string> &v, vector<int> &answers){
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            canMove(i,j,n,v,answers);
        }
    }
    return answers.size();
}

int main()
{
    vector<int> answers;
    vector<string> v;
    string s;
    cin >> s;
    int n = sqrt((double)s.size());
    for (int i = 0; i < n; i++)
    {
        v.push_back(string(s.begin()+i*n,s.begin()+i*n+n));
    }
    if (game(n,v,answers))
    {
        cout << "YES ";
        for (unsigned i = 0; i < answers.size(); i++)
        {
            cout << answers[i]+1 << " ";
        }
    }
    else
    {
        cout << "NO";
    }
    cout << endl;
    return 0;
}

第五十八题

58.问题描述:
把一个字符串中的除大写字母、小写字母和数字字符之外的其他字符都去掉,输出新字符串。

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

bool isChar(char c){
    if (c >= 'a' && c <= 'z')
    {
        return true;
    }
    if (c >= 'A' && c <= 'Z')
    {
        return true;
    }
    if (c >= '0' && c <= '9')
    {
        return true;
    }
    return false;
}

void filt(const string &s1, string &s2){
    for (unsigned i = 0; i < s1.size(); i++)
    {
        if (isChar(s1[i]))
        {
            s2.push_back(s1[i]);
        }
    }
}

int main()
{
    string s, output;
    getline(cin,s);
    filt(s,output);
    cout << output << endl;
    return 0;
}

第五十九题

59.正数减法
问题描述:
两个任意长度的正数相减,这两个正数可以带小数点,也可以是整数,请输出结果。 输入的字符串中,不会出现除了数字与小数点以外的其它字符,不会出现多个小数点以及小数点在第一个字符的位置等非法情况,所以考生的程序中无须考虑输入的数值字符串非法的情况。
详细要求以及约束:
1.输入均为正数,但输出可能为负数;
2.输入输出均为字符串形式;
3.如果输出是正数则不需要带符号,如果为负数,则输出的结果字符串需要带负号
例如:2.2-1.1 直接输出为“1.1”,1.1-2.2 则需要输出为“-1.1”
4.输出的结果字符串需要过滤掉整数位前以及小数位后无效的0,小数位为全0的,直接输出整数位
例如相减结果为11.345,此数值前后均不可以带0,“011.345”或者“0011.34500”等等前后带无效0的均视为错误 输出。例如1.1-1.1结果为0.0,则直接输出0。
要求实现函数:
void Decrease(char *input1, char*input2, char *output)
【输入】 char *iinput1 被减数
char*nput2 减数
【输出】 char *output 减法结果
【返回】 无
示例
输入:char *input1=”2.2”
char *input2=”1.1”
输出:char*output=”1.1”
输入:char *input1=”1.1”
char *input2=”2.2”
输出:char *output=”-1.1”

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

void divive(const string &s, string &si, string &sf){
    int pos = s.find('.');
    if (pos >= 0)
    {
        si = string(s.begin(),s.begin()+pos);
        sf = string(s.begin()+pos+1,s.end());
    }
    else
    {
        si = s;
        sf = "0";
    }
}


int compute(const string &s1, const string &s2, int overFlow, string &result){
    auto b1 = s1.rbegin(), b2 = s2.rbegin();
    while (b1 != s1.rend() && b2 != s2.rend())
    {
        int value = (*b1++ - '0') - (*b2++ - '0') - overFlow;
        if (value < 0)
        {
            overFlow = 1;
            result.push_back(value+10+ '0');
        }
        else
        {
            overFlow = 0;
            result.push_back(value + '0');
        }
    }
    return overFlow;
}

void Decrease(char *input1, char*input2, char *output){
    string s1(input1,strlen(input1)), s2(input2,strlen(input2)),s3;
    string si1,si2,sf1,sf2;
    divive(s1,si1,sf1);
    divive(s2,si2,sf2);

    int byte1 = si1.size() - si2.size();
    int byte2 = sf1.size() - sf2.size();

    if (byte1 < 0)
    {
        si1.insert(si1.begin(),-byte1,'0');
    }
    else if (byte1 > 0)
    {
        si2.insert(si2.begin(),byte1,'0');
    }

    if (byte2 < 0)
    {
        sf1.insert(sf1.end(),-byte2,'0');
    }
    else if (byte2 > 0)
    {
        sf2.insert(sf2.end(),byte2,'0');
    }

    string iresult,fresult;
    bool flag;
    if (si1 == si2 && sf1 == sf2)
    {
        *output++ = '0';
        *output = '\0';
        return;
    }
    else if (si1 > si2 || (si1 == si2 && sf1 > sf2))
    {
        flag = 0;
        int overFlow = compute(sf1,sf2,0,fresult);
        compute(si1,si2,overFlow,iresult);
    }
    else
    {
        flag = 1;
        int overFlow = compute(sf2,sf1,0,fresult);
        compute(si2,si1,overFlow,iresult);
    }

    int pos = iresult.find_last_not_of('0');
    if (pos < 0)
    {
        iresult = flag ? "-0" :"0";
    }
    else
    {
        iresult.erase(iresult.begin()+pos+1,iresult.end());
        reverse(iresult.begin(),iresult.end());
        if (flag)
        {
            iresult.insert(iresult.begin(),'-');
        }
    }

    reverse(fresult.begin(),fresult.end());
    pos = fresult.find_last_not_of('0');
    if (pos < 0)
    {
        s3 = iresult;
    }
    else
    {
        fresult.erase(fresult.begin()+pos+1,fresult.end());
        s3 = iresult + "." + fresult;
    }

    for (unsigned i = 0; i < s3.size(); i++)
    {
        *output++ = s3[i];
    }
    *output = '\0';
}

int main()
{
    char s1[100],s2[100],output[100];
    cin.getline(s1,100);
    cin.getline(s2,100);

    Decrease(s1,s2,output);
    cout << output << endl;
    return 0;
}

第六十题

60.判断比整数N小的数里,有多少个与7相关的数。与7相关指:7的倍数或者带有7的数(比如7、14、17、27)。只需要给出总的个数,不需要输出
它们(N小于30000)

#include <iostream>
using namespace std;

bool isRight(int n){
    if (n % 7 == 0)
    {
        return true;
    }
    while (n != 0)
    {
        if (n % 10 == 7)
        {
            return true;
        }
        n /= 10;
    }
    return false;
}

int count7(int n){
    if (n < 0 || n >= 30000)
    {
        return -1;
    }
    int count = 0;
    for (int i = 0; i < n; i++)
    {
        if (isRight(i))
        {
            count++;
        }
    }
    return count;
}

int main()
{
    int n;
    cin >> n;
    cout << count7(n) << endl;
    return 0;
}