东方博宜oj1120——1129 - 详解


解析在后面

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 类型
计算并输出乘积
例子: "100
200="
starPos = 3(* 在索引3)
equalPos = 7(= 在索引7)
num1Str = “100”(索引0-2)
num2Str = “200”(索引4-6)
计算:100 * 200 = 20000

好啦,支持一下作者叭
看到这里了,不点个赞再走嘛?
QWQ,开玩笑的!!!!!!不要真走啊!!!!
来我主页逛逛叭~

posted on 2025-10-28 15:04  blfbuaa  阅读(15)  评论(0)    收藏  举报