机试day5
特殊乘法
描述
写个算法,对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);
}
}
密码翻译
描述
在情报传递过程中,为了防止情报被截获,往往需要对情报用一定的方式加密,简单的加密算法虽然不足以完全避免情报被破译,但仍然能防止情报被轻易的识别。我们给出一种最简的的加密方法,对给定的一个字符串,把其中从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;
}
}
简单密码
描述
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;
}
}
}
统计字符
描述
统计一个给定字符串中指定的字符出现的次数。
输入描述:
测试输入包含若干测试用例,每个测试用例包含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);
}
}
}
字母统计
描述
输入一行字符串,计算其中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 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);
}
}
单词替换
描述
输入一个字符串,以回车结束(字符串长度<=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++实现较难