东方博宜oj1120——1129 - 详解
东方博宜oj1120-1129
- 1120 - 倒置输出字符串
- 1121 - “倒”数
- 1122 - 计算表达式
- 1123 - 表达式的值
- 1124 - 表达式的值II
- 1125 - 删除字符串中间的*
- 1126 - 英文翻译
- 1127 - 整数的拼接
- 1128 - 整数串拆段
- 1129 - 简单a*b
- ——————答案与解析分割线——————
- 1120 - 倒置输出字符串 解析
- 1121 - “倒”数 解析
- 1122 - 计算表达式 解析
- 1123 - 表达式的值 解析
- 1124 - 表达式的值II 解析
- 1125 - 删除字符串中间的* 解析
- 1126 - 英文翻译 解析
- 1127 - 整数的拼接 解析
- 1128 - 整数串拆段 解析
- 1129 - 简单a*b 解析
解析在后面
1120 - 倒置输出字符串
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
for (int i = s.length() - 1; i >= 0; i--) {
cout << s[i];
}
return 0;
}
1121 - “倒”数
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int reversed = 0;
while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}
cout << reversed << endl;
return 0;
}
1122 - 计算表达式
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int result = s[0] - '0'; // 第一个数字
for (int i = 1; i < s.length(); i += 2) {
char op = s[i]; // 运算符
int num = s[i + 1] - '0'; // 下一个数字
if (op == '+') {
result += num;
} else if (op == '-') {
result -= num;
} else if (op == '*') {
result *= num;
}
}
cout << result << endl;
return 0;
}
1123 - 表达式的值
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int sum = 0;
int num = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '+') {
sum += num;
num = 0; // 重置当前数字
} else {
num = num * 10 + (s[i] - '0'); // 构建多位数
}
}
// 加上最后一个数字
sum += num;
cout << sum << endl;
return 0;
}
1124 - 表达式的值II
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int result = 0;
int num = 0;
char op = '+'; // 第一个数字前面可以看作有+
for (int i = 0; i < s.length(); i++) {
if (s[i] >= '0' && s[i] <= '9') {
num = num * 10 + (s[i] - '0'); // 构建多位数
}
// 遇到运算符或者到达字符串末尾
if (s[i] == '+' || s[i] == '-' || i == s.length() - 1) {
if (op == '+') {
result += num;
} else if (op == '-') {
result -= num;
}
// 更新运算符和重置数字
op = s[i];
num = 0;
}
}
cout << result << endl;
return 0;
}
1125 - 删除字符串中间的*
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
// 找到第一个非*字符的位置
int start = 0;
while (start < s.length() && s[start] == '*') {
start++;
}
// 找到最后一个非*字符的位置
int end = s.length() - 1;
while (end >= 0 && s[end] == '*') {
end--;
}
// 构建结果字符串
string result = "";
// 添加开头的*
for (int i = 0; i < start; i++) {
result += s[i];
}
// 添加中间部分(删除*)
for (int i = start; i <= end; i++) {
if (s[i] != '*') {
result += s[i];
}
}
// 添加结尾的*
for (int i = end + 1; i < s.length(); i++) {
result += s[i];
}
cout << result << endl;
return 0;
}
1126 - 英文翻译
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 0-19的英文
vector<string> ones = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
// 20-90的英文
vector<string> tens = {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
// 处理三位数
string convertThreeDigits(int num) {
if (num == 0) return "";
string result = "";
int hundreds = num / 100;
int remainder = num % 100;
if (hundreds > 0) {
result += ones[hundreds] + " hundred";
if (remainder > 0) {
result += " and ";
}
}
if (remainder > 0) {
if (remainder < 20) {
result += ones[remainder];
} else {
result += tens[remainder / 10];
if (remainder % 10 > 0) {
result += " " + ones[remainder % 10];
}
}
}
return result;
}
int main() {
long long n;
cin >> n;
if (n == 0) {
cout << "zero" << endl;
return 0;
}
vector<string> result;
vector<string> units = {"billion", "million", "thousand", ""};
vector<long long> divisors = {1000000000, 1000000, 1000, 1};
for (int i = 0; i < 4; i++) {
int segment = n / divisors[i];
if (segment > 0) {
string segmentStr = convertThreeDigits(segment);
if (!segmentStr.empty()) {
if (!units[i].empty()) {
segmentStr += " " + units[i];
}
result.push_back(segmentStr);
}
n %= divisors[i];
}
}
// 输出结果
for (int i = 0; i < result.size(); i++) {
if (i > 0) cout << " ";
cout << result[i];
}
cout << endl;
return 0;
}
1127 - 整数的拼接
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 自定义比较函数
bool compare(string a, string b) {
return a + b > b + a; // 按拼接后的大小降序排列
}
int main() {
int n;
cin >> n;
vector<string> nums;
for (int i = 0; i < n; i++) {
string num;
cin >> num;
nums.push_back(num);
}
// 按自定义规则排序
sort(nums.begin(), nums.end(), compare);
// 拼接结果
string result = "";
for (string num : nums) {
result += num;
}
cout << result << endl;
return 0;
}
1128 - 整数串拆段
#include <iostream>
#include <string>
#include <climits>
using namespace std;
// 判断是否为素数
bool isPrime(int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
string s;
cin >> s;
int minPrime = INT_MAX;
bool found = false;
// 枚举所有拆分位置(从第1个字符后到倒数第1个字符后)
for (int i = 1; i < s.length(); i++) {
string part1 = s.substr(0, i); // 第一部分
string part2 = s.substr(i); // 第二部分
int num1 = stoi(part1);
int num2 = stoi(part2);
int sum = num1 + num2;
if (isPrime(sum)) {
if (sum < minPrime) {
minPrime = sum;
}
found = true;
}
}
if (found) {
cout << minPrime << endl;
} else {
cout << -1 << endl;
}
return 0;
}
1129 - 简单a*b
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
// 找到 * 和 = 的位置
int starPos = s.find('*');
int equalPos = s.find('=');
// 提取两个数字
string num1Str = s.substr(0, starPos);
string num2Str = s.substr(starPos + 1, equalPos - starPos - 1);
// 转换为整数并计算
long long num1 = stoll(num1Str);
long long num2 = stoll(num2Str);
long long result = num1 * num2;
cout << result << endl;
return 0;
}
——————答案与解析分割线——————
1120 - 倒置输出字符串 解析
这道题要求将输入的字符串倒序输出。
输入字符串长度不超过 255,且不含空格。
思路:
读入字符串
从最后一个字符开始,向前遍历,依次输出
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
for (int i = s.length() - 1; i >= 0; i--) {
cout << s[i];
}
return 0;
}
这个程序很简单:
用 string 类型读取输入的字符串
从字符串最后一个字符开始向前遍历
依次输出每个字符
例如输入 asdfghjkl123456,就会输出 654321lkjhgfdsa
1121 - “倒”数 解析
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int reversed = 0;
while (n > 0) {
reversed = reversed * 10 + n % 10;
n /= 10;
}
cout << reversed << endl;
return 0;
}
思路说明:
用 n % 10 获取最后一位数字
用 reversed * 10 + n % 10 将数字添加到反转数的末尾
用 n /= 10 去掉最后一位
重复直到原数变为0
例子:
输入:345
第1次:n=345, reversed=0×10+5=5, n=34
第2次:n=34, reversed=5×10+4=54, n=3
第3次:n=3, reversed=54×10+3=543, n=0
输出:543
这种方法自动处理了前导零的问题,因为反转后的数字是整数,前导零不会显示。
1122 - 计算表达式 解析
这道题的关键是:没有优先级,一律从左向右计算。
所以我们可以:
读取第一个数字作为初始结果
然后每次读取一个运算符和一个数字,立即计算
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int result = s[0] - '0'; // 第一个数字
for (int i = 1; i < s.length(); i += 2) {
char op = s[i]; // 运算符
int num = s[i + 1] - '0'; // 下一个数字
if (op == '+') {
result += num;
} else if (op == '-') {
result -= num;
} else if (op == '*') {
result *= num;
}
}
cout << result << endl;
return 0;
}
解释:
字符串格式一定是:数字、运算符、数字、运算符、数字…
所以从索引1开始,每隔一个位置就是运算符,下一个位置就是数字
每次读取到运算符和数字后立即计算
例子: "3+56-4"
初始:result = 3
i=1:op=‘+’, num=5 → 3+5=8
i=3:op='‘, num=6 → 8*6=48
i=5:op=’-', num=4 → 48-4=44
输出:44
1123 - 表达式的值 解析
这道题和前一题的区别是:数字可能不止一位,但只有加法运算。
我们需要:
遍历字符串
提取出每个数字(可能有多位)
把所有数字相加
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int sum = 0;
int num = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '+') {
sum += num;
num = 0; // 重置当前数字
} else {
num = num * 10 + (s[i] - '0'); // 构建多位数
}
}
// 加上最后一个数字
sum += num;
cout << sum << endl;
return 0;
}
解释:
用 num 变量来构建当前正在读取的数字
遇到数字字符时:num = num × 10 + (当前数字)
遇到 + 时:把当前数字加到总和,然后重置 num
循环结束后记得加上最后一个数字
例子: “12+23”
i=0:s[0]=‘1’ → num = 0×10+1 = 1
i=1:s[1]=‘2’ → num = 1×10+2 = 12
i=2:s[2]=‘+’ → sum = 0+12 = 12, num = 0
i=3:s[3]=‘2’ → num = 0×10+2 = 2
i=4:s[4]=‘3’ → num = 2×10+3 = 23
循环结束:sum = 12+23 = 35
输出:35
1124 - 表达式的值II 解析
这道题在上一题基础上增加了减法运算,但思路类似。
我们需要:
记录当前数字和当前运算符
遇到运算符时,根据前一个运算符进行计算
第一个数字前面可以看作有一个隐含的 +
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
int result = 0;
int num = 0;
char op = '+'; // 第一个数字前面可以看作有+
for (int i = 0; i < s.length(); i++) {
if (s[i] >= '0' && s[i] <= '9') {
num = num * 10 + (s[i] - '0'); // 构建多位数
}
// 遇到运算符或者到达字符串末尾
if (s[i] == '+' || s[i] == '-' || i == s.length() - 1) {
if (op == '+') {
result += num;
} else if (op == '-') {
result -= num;
}
// 更新运算符和重置数字
op = s[i];
num = 0;
}
}
cout << result << endl;
return 0;
}
解释:
用 op 记录前一个运算符
遇到新的运算符时,根据前一个运算符进行计算
计算后更新 op 为当前运算符
字符串末尾也要处理最后一个数字
例子: “12+23-11”
初始:result=0, num=0, op=‘+’
读取"12":num=12
遇到’+‘:result=0+12=12,op=’+‘,num=0
读取"23":num=23
遇到’-‘:result=12+23=35,op=’-',num=0
读取"11":num=11
到达末尾:result=35-11=24
输出:24
1125 - 删除字符串中间的* 解析
这道题要求删除字符串中间的 *,但保留开头和结尾的 *。
思路:
找到第一个非 * 字符的位置
找到最后一个非 * 字符的位置
在这两个位置之间的部分,删除所有的 *
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
// 找到第一个非*字符的位置
int start = 0;
while (start < s.length() && s[start] == '*') {
start++;
}
// 找到最后一个非*字符的位置
int end = s.length() - 1;
while (end >= 0 && s[end] == '*') {
end--;
}
// 构建结果字符串
string result = "";
// 添加开头的*
for (int i = 0; i < start; i++) {
result += s[i];
}
// 添加中间部分(删除*)
for (int i = start; i <= end; i++) {
if (s[i] != '*') {
result += s[i];
}
}
// 添加结尾的*
for (int i = end + 1; i < s.length(); i++) {
result += s[i];
}
cout << result << endl;
return 0;
}
解释:
start 指向第一个非 * 字符(即开头 * 的结束位置)
end 指向最后一个非 * 字符(即结尾 * 的开始位置)
结果由三部分组成:
开头 *(原样保留)
中间部分(删除所有 *)
结尾 *(原样保留)
例子: " *** ABC123 ** 123 * abc ** ** * ** ** ** "
开头 *:" * * * "
中间部分:“ABC123123abc”(删除了中间的 * )
结尾 * :" *********** "
输出:" *** ABC123123abc ***********"
(有空格请见谅,不然它会自动变粗呜呜呜┭┮﹏┭┮)
1126 - 英文翻译 解析
这是一个比较复杂的题目,需要将数字分段处理(billion, million, thousand),并且注意"and"的使用规则。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 0-19的英文
vector<string> ones = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
// 20-90的英文
vector<string> tens = {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
// 处理三位数
string convertThreeDigits(int num) {
if (num == 0) return "";
string result = "";
int hundreds = num / 100;
int remainder = num % 100;
if (hundreds > 0) {
result += ones[hundreds] + " hundred";
if (remainder > 0) {
result += " and ";
}
}
if (remainder > 0) {
if (remainder < 20) {
result += ones[remainder];
} else {
result += tens[remainder / 10];
if (remainder % 10 > 0) {
result += " " + ones[remainder % 10];
}
}
}
return result;
}
int main() {
long long n;
cin >> n;
if (n == 0) {
cout << "zero" << endl;
return 0;
}
vector<string> result;
vector<string> units = {"billion", "million", "thousand", ""};
vector<long long> divisors = {1000000000, 1000000, 1000, 1};
for (int i = 0; i < 4; i++) {
int segment = n / divisors[i];
if (segment > 0) {
string segmentStr = convertThreeDigits(segment);
if (!segmentStr.empty()) {
if (!units[i].empty()) {
segmentStr += " " + units[i];
}
result.push_back(segmentStr);
}
n %= divisors[i];
}
}
// 输出结果
for (int i = 0; i < result.size(); i++) {
if (i > 0) cout << " ";
cout << result[i];
}
cout << endl;
return 0;
}
算法说明:
分段处理:将数字按 billion(10⁹), million(10⁶), thousand(10³) 分段
三位数转换:convertThreeDigits 函数处理每三位数
处理百位:X hundred
处理十位和个位:注意 0-19 的特殊单词
在百位和十/个位之间加 “and”
特殊情况:数字为 0 时直接输出 “zero”
例子: 1111111111
billion段:1 → “one billion”
million段:111 → “one hundred and eleven million”
thousand段:111 → “one hundred and eleven thousand”
个位段:111 → “one hundred and eleven”
最终:“one billion one hundred and eleven million one hundred and eleven thousand one hundred and eleven”
1127 - 整数的拼接 解析
这道题的关键是自定义排序规则:不是简单按数值大小,而是按字符串拼接后的大小来排序。
比如:
7 和 34:比较 “734” 和 “347”,因为 “734” > “347”,所以 7 应该排在 34 前面
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 自定义比较函数
bool compare(string a, string b) {
return a + b > b + a; // 按拼接后的大小降序排列
}
int main() {
int n;
cin >> n;
vector<string> nums;
for (int i = 0; i < n; i++) {
string num;
cin >> num;
nums.push_back(num);
}
// 按自定义规则排序
sort(nums.begin(), nums.end(), compare);
// 拼接结果
string result = "";
for (string num : nums) {
result += num;
}
cout << result << endl;
return 0;
}
算法说明:
将数字作为字符串读入
自定义排序规则:比较 a+b 和 b+a,哪个大就把哪个放在前面
将所有字符串拼接起来
例子分析:
输入:21, 7, 34
比较 “21” 和 “7”:“217” vs “721” → “721” 更大,所以 7 在 21 前
比较 “7” 和 “34”:“734” vs “347” → “734” 更大,所以 7 在 34 前
比较 “21” 和 “34”:“2134” vs “3421” → “3421” 更大,所以 34 在 21 前
最终顺序:7, 34, 21
输出:“73421”
另一个例子: 1, 10, 110
“1” 和 “10”:“110” vs “101” → “110” 更大,所以 1 在 10 前
“1” 和 “110”:“1110” vs “1101” → “1110” 更大,所以 1 在 110 前
“10” 和 “110”:“10110” vs “11010” → “11010” 更大,所以 110 在 10 前
最终顺序:1, 110, 10
输出:“111010”
1128 - 整数串拆段 解析
这道题需要:
枚举所有可能的拆分方式
计算两段数字的和
检查是否为素数
找出最小的素数
#include <iostream>
#include <string>
#include <climits>
using namespace std;
// 判断是否为素数
bool isPrime(int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
int main() {
string s;
cin >> s;
int minPrime = INT_MAX;
bool found = false;
// 枚举所有拆分位置(从第1个字符后到倒数第1个字符后)
for (int i = 1; i < s.length(); i++) {
string part1 = s.substr(0, i); // 第一部分
string part2 = s.substr(i); // 第二部分
int num1 = stoi(part1);
int num2 = stoi(part2);
int sum = num1 + num2;
if (isPrime(sum)) {
if (sum < minPrime) {
minPrime = sum;
}
found = true;
}
}
if (found) {
cout << minPrime << endl;
} else {
cout << -1 << endl;
}
return 0;
}
算法说明:
枚举拆分:对于长度为 n 的字符串,有 n-1 种拆分方式
字符串转数字:使用 substr 分割,stoi 转换
素数判断:从 2 到 √n 检查是否能整除
记录最小值:找到所有素数中的最小值
例子分析: “13304”
拆分1:1 + 3304 = 3305(不是素数)
拆分2:13 + 304 = 317(素数)
拆分3:133 + 04 = 137(素数)
拆分4:1330 + 4 = 1334(不是素数)
最小素数:137
特殊情况: “2468”
所有拆分方式的和都不是素数
输出:-1
1129 - 简单a*b 解析
(OS:难度跨越太大了吧,这么简单?!?!)
这道题需要从输入字符串中提取出两个乘数,然后计算它们的乘积。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s;
// 找到 * 和 = 的位置
int starPos = s.find('*');
int equalPos = s.find('=');
// 提取两个数字
string num1Str = s.substr(0, starPos);
string num2Str = s.substr(starPos + 1, equalPos - starPos - 1);
// 转换为整数并计算
long long num1 = stoll(num1Str);
long long num2 = stoll(num2Str);
long long result = num1 * num2;
cout << result << endl;
return 0;
}
算法说明:
使用 find('‘) 找到乘号的位置
使用 find(’=') 找到等号的位置
用 substr 提取两个数字字符串:
第一个数字:从开始到 * 之前
第二个数字:从 * 之后到 = 之前
用 stoll 转换为 long long 类型
计算并输出乘积
例子: "100200="
starPos = 3(* 在索引3)
equalPos = 7(= 在索引7)
num1Str = “100”(索引0-2)
num2Str = “200”(索引4-6)
计算:100 * 200 = 20000
好啦,支持一下作者叭
看到这里了,不点个赞再走嘛?
QWQ,开玩笑的!!!!!!不要真走啊!!!!
来我主页逛逛叭~
浙公网安备 33010602011771号