机试day5

特殊乘法

特殊乘法_牛客题霸_牛客网 (nowcoder.com)

描述

写个算法,对2个小于1000000000的输入,求结果。 特殊乘法举例:123 * 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5

输入描述

两个小于1000000000的数

输出描述

输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

思路:数字转为字符串,单个单个字符串计算

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

int main() {
    string num1, num2;
    int result;
    while (cin >> num1 >> num2) {
        result = 0;
        for (int i = 0; i < num1.size(); i++) {
            for (int j = 0; j < num2.size(); j++) {
                result += (num1[i] - '0') * (num2[j] - '0');
            }
        }
        printf("%d\n", result);
    }
}

密码翻译

密码翻译_牛客题霸_牛客网 (nowcoder.com)

描述

在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从a-y,A-Y的字母用其后继字母替代,把z和Z用a和A替代,则可得到一个简单的加密字符串。

输入描述

读取这一行字符串,每个字符串长度小于80个字符

输出描述

对于每组数据,输出每行字符串的加密字符串。

思路:同上题,因为类似转筒,所以用到了模数,注意点直接cin或者scanf无法接收带有空格的字符串,因此要用getline(cin, s),它以回车作为间隔

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

int main() {
    string s;
    while (getline(cin, s)) {
        for (int i = 0; i < s.size(); i++) {
            if (s[i] >= 'a' && s[i] <= 'z') {
                s[i] = (s[i] - 'a' + 1) % 26 + 'a';
            } else if (s[i] >= 'A' && s[i] <= 'Z') {
                s[i] = (s[i] - 'A' + 1) % 26 + 'A';
            }
        }
        cout << s << endl;
    }
}

简单密码

简单密码_牛客题霸_牛客网 (nowcoder.com)

描述

Julius Caesar曾经使用过一种很简单的密码。 对于明文中的每个字符,将它用它字母表中后5位对应的字符来代替,这样就得到了密文。 比如字符A用F来代替。如下是密文和明文中字符的对应关系。 密文 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 明文 V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 你的任务是对给定的密文进行解密得到明文。 你需要注意的是,密文中出现的字母都是大写字母。密文中也包括非字母的字符,对这些字符不用进行解码。

输入描述

输入中的测试数据不超过100组。每组数据都有如下的形式,而且各组测试数据之间没有空白的行。 一组测试数据包括三部分: 1. 起始行 - 一行,包括字符串 "START" 2. 密文 - 一行,给出密文,密文不为空,而且其中的字符数不超过200 3. 结束行 - 一行,包括字符串 "END" 在最后一组测试数据之后有一行,包括字符串 "ENDOFINPUT"。

输出描述

对每组数据,都有一行输出,给出密文对应的明文。

输入:
START
NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
END
START
N BTZQI WFYMJW GJ KNWXY NS F QNYYQJ NGJWNFS ANQQFLJ YMFS XJHTSI NS WTRJ
END
START
IFSLJW PSTBX KZQQ BJQQ YMFY HFJXFW NX RTWJ IFSLJWTZX YMFS MJ
END
ENDOFINPUT
输出:
IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES
I WOULD RATHER BE FIRST IN A LITTLE IBERIAN VILLAGE THAN SECOND IN ROME
DANGER KNOWS FULL WELL THAT CAESAR IS MORE DANGEROUS THAN HE

思路:注意减回去时小于A的返回Z继续

#include <iostream>
using namespace std;

int main() {
    string s;
    while (getline(cin, s)) { 
        if (s == "START" || s == "END") {
            continue;
        } else if (s == "ENDOFINPUT") {
            break;
        } else {
            for (int i = 0; i < s.size(); i++) {
                if (s[i] >= 'A' && s[i] <= 'Z')
                    s[i] = (s[i] - 'A' - 5 + 26) % 26 + 'A';
            }
            cout << s << endl;
        }
    }
}

统计字符

统计字符_牛客题霸_牛客网 (nowcoder.com)

描述

统计一个给定字符串中指定的字符出现的次数。

输入描述

测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串。注意这里的字符串包含空格,即空格也可能是要求被统计的字符之一。当读到'#'时输入结束,相应的结果不要输出。

输出描述

对每个测试用例,统计第1行中字符串的每个字符在第2行字符串中出现的次数,按如下格式输出: c0 n0 c1 n1 c2 n2 ... 其中ci是第1行中第i个字符,ni是ci出现的次数。

输入:
I
THIS IS A TEST
i ng
this is a long test string
#
输出:
I 2
i 3
  5
n 2
g 2

思路:一个个比较就好了,注意对结束符的判断

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

int main() {
    string s1, s2;
    while (getline(cin, s1)) { 
        if (s1 == "#")
            break;
        getline(cin, s2);
        int num;
        for (int i = 0; i < s1.size(); i++) {
            num = 0;
            for (int j = 0; j < s2.size(); j++) {
                if (s2[j] == s1[i])
                    num++;  
            }
            printf("%c %d\n", s1[i], num);
        }
    }
}

字母统计

字母统计_牛客题霸_牛客网 (nowcoder.com)

描述

输入一行字符串,计算其中A-Z大写字母出现的次数

输入描述

案例可能有多组,每个案例输入为一行字符串。

输出描述

对每个案例按A-Z的顺序输出其中大写字母出现的次数。

输入:
DFJEIWFNQLEF0395823048+_+JDLSFJDLSJFKK
输出:
A:0
B:0
C:0
D:3
E:2
F:5
G:0
H:0
I:1
J:4
K:2
L:3
M:0
N:1
O:0
P:0
Q:1
R:0
S:2
T:0
U:0
V:0
W:1
X:0
Y:0
Z:0

思路:设置一个数组,遍历每个字符,如果在A-Z的范围内,则在该字母上加一次,最后使用printf输出,'A'+i可以格式化为字符

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

int main() {
    string s;
    while (cin >> s) {
        int c[26] = {0};
        for (int i = 0; i < s.size(); i++) {
            if (s[i] >= 'A' && s[i] <= 'Z') {
                c[s[i] - 'A']++;
            }
        }
        for (int i = 0; i < 26; i++) {
            printf("%c:%d\n", 'A' + i, c[i]);
        }
    }
}

skew数

skew数_牛客题霸_牛客网 (nowcoder.com)

描述

在 skew binary 表示中,第 k 位的值 x[k] 表示 x[k]×(2^(k+1)-1)。每个位上的可能数字是 0 或 1,最后面一个非零位可以是 2,例如,10120(skew) = 1×(2^5-1) + 0×(2^4-1) + 1×(2^3-1) + 2×(2^2-1) + 0×(2^1-1) = 31 + 0 + 7 + 6 + 0 = 44。前十个 skew 数是 0、1、2、10、11、12、20、100、101、以及 102。

输入描述

输入包括多组数据,每组数据包含一个 skew 数。

输出描述

对应每一组数据,输出相应的十进制形式。结果不超过 2^31-1。

思路:输入明显视为字符串的话更好计算

#include <cmath>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;

int main() {
    string s;
    int skew;
    while (cin >> s) {
        skew = 0;
        for (int i = s.size(); i > 0; i--) {
            skew += (s[s.size() - i] - '0') * (pow(2, i) - 1);
        }
        printf("%d\n", skew);
    }
}

单词替换

单词替换_牛客题霸_牛客网 (nowcoder.com)

描述

输入一个字符串,以回车结束(字符串长度<=100)。该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写。现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符串。

输入描述

每组数据输入包括3行,第1行是包含多个单词的字符串s,第2行是待替换的单词a(长度<=100),第3行是a将被替换的单词b(长度<=100)。s, a, b 最前面和最后面都没有空格。

输出描述

每个测试数据输出只有 1 行, 将s中所有单词a替换成b之后的字符串。

输入:
You want someone to help you
You
I
输出:
I want someone to help you

首先贴出错误的代码:下面这个代码没有好好读题,是把单词替换掉,而非所有匹配字符串替换掉,比方说一个单词是CCCCC,要被替换的是CCC,这个CCCCC是不应该不替换的,尽管这个单词里包含了CCC

#include <iostream>
using namespace std;

int main() {
    string s, a, b;
    while (getline(cin, s)) {
        cin >> a >> b;
        int index[100] = {0};
        int i = 0, find_i = 0;
        while ((find_i = s.find(a, find_i)) != string::npos) {
            index[i] = find_i;
            find_i += a.size();
            i++;
        }
        for (int j = 0; j < i; j++) {
            s.erase(index[j], a.size());
            s.insert(index[j], b);
        }
        cout << s << endl;
    }
}

正确且十分恰当的思路:利用题目中说s、a、b前后都没空格的提示,把三个字符串前后都加上空格,从而把每个单词包含了前后的空格视为一个整体来查找!代码也更加简洁

#include <iostream>
using namespace std;

int main() {
    string s, a, b;
    while (getline(cin, s)) {
        cin >> a >> b;
        s = ' ' + s + ' ';
        a = ' ' + a + ' ';
        b = ' ' + b + ' ';
        int find_i = 0;
        while ((find_i = s.find(a, find_i)) != string::npos) {
            s.erase(find_i, a.size());
            s.insert(find_i, b);
        }
        cout << s.substr(1, s.size() - 2) << endl;
    }
}

其他思路:按照空格划分句子,这点在python中很好用,C++实现较难

最后修改:2023 年 05 月 31 日
如果觉得我的文章对你有用,请随意赞赏