小S求解特殊算术题解 | 豆包MarsCode AI刷题

76 阅读5分钟

一、小S求解特殊算术

1.1 题目描述

现有若干整数相加的公式,例如:123+3456L2+789R4+502S,需要编写程序计算其结果。

其中:

  1. 每个加数可能带有后缀,后缀含义如下:

    • Lx 表示将该加数向左循环移位 x 次后再参与运算。
    • Rx 表示将该加数向右循环移位 x 次后再参与运算。
    • S 表示将该加数翻转(即数字逆序)后再参与运算。
    • 无后缀的加数直接参与运算。
  2. 整数的左移和右移说明:

    • 数字 AB...CD 向右循环移位 1 次,将变为 DAB...C
    • 数字 AB...CD 向左循环移位 1 次,将变为 B...CDA
  3. 输入的公式中整数的个数不超过 20,且均为正整数,移位次数不会超出整数位数,所有计算不会超过 int 型数据范围。

输入格式

一行,给出一个加法公式,公式中的加数为正整数,可能附带后缀。


输出格式

计算这些整数的相加和。


输入样例
123+3456L2+789R4+502S

输出样例
6940

1.2 思路分析

  • 解析输入公式

    • 将输入公式按照加号(+)分割成多个部分,每部分是一个数字及其可能的后缀(如 LxRxS)。
    • 使用字符串分割函数(如 strtok)解析每个加数及其后缀。
  • 处理后缀操作

    • 判断每个加数是否带有后缀,后缀表示操作类型:

      • Lx:向左循环移位 x 次。
      • Rx:向右循环移位 x 次。
      • S:翻转数字。
    • 对于无后缀的加数,直接参与计算。

  • 实现移位和翻转逻辑

    • 循环移位

      • 使用字符串操作,将数字转为字符串后进行移位,最后将移位结果转回整数。
      • 左移时,将前面的数字移到后面;右移时,将后面的数字移到前面。
    • 翻转数字

      • 将数字转为字符串,倒序后再转换回整数。
  • 累加结果

    • 逐步处理每个加数,按照规则转换后将结果累加。
  • 输出最终结果

    • 计算完所有加数后,输出累加和。

1.3 题目解答(C语言)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 函数:将数字向左循环移位
int leftRotate(int num, int times) {
    char str[20];
    sprintf(str, "%d", num);  // 将数字转换为字符串
    int len = strlen(str);
    times = times % len;      // 确保移位次数不超过长度

    char rotated[20];
    for (int i = 0; i < len; i++) {
        rotated[i] = str[(i + times) % len];
    }
    rotated[len] = '\0';      // 添加字符串结束符

    return atoi(rotated);     // 转换为整数返回
}

// 函数:将数字向右循环移位
int rightRotate(int num, int times) {
    char str[20];
    sprintf(str, "%d", num);  // 将数字转换为字符串
    int len = strlen(str);
    times = times % len;      // 确保移位次数不超过长度

    char rotated[20];
    for (int i = 0; i < len; i++) {
        rotated[(i + times) % len] = str[i];
    }
    rotated[len] = '\0';      // 添加字符串结束符

    return atoi(rotated);     // 转换为整数返回
}

// 函数:将数字翻转
int reverseNumber(int num) {
    char str[20];
    sprintf(str, "%d", num);  // 将数字转换为字符串
    int len = strlen(str);

    char reversed[20];
    for (int i = 0; i < len; i++) {
        reversed[i] = str[len - 1 - i];
    }
    reversed[len] = '\0';     // 添加字符串结束符

    return atoi(reversed);    // 转换为整数返回
}

// 主函数
int main() {
    char input[100];
    scanf("%s", input);  // 读取输入的加法公式

    int result = 0;  // 存储最终结果
    char *token = strtok(input, "+");  // 以 '+' 分割公式

    while (token != NULL) {
        int num;
        char suffix[10] = "";  // 存储后缀
        sscanf(token, "%d%[LR0123456789S]", &num, suffix);

        // 根据后缀类型处理数字
        if (suffix[0] == 'L') {
            int times = atoi(suffix + 1);
            num = leftRotate(num, times);
        } else if (suffix[0] == 'R') {
            int times = atoi(suffix + 1);
            num = rightRotate(num, times);
        } else if (suffix[0] == 'S') {
            num = reverseNumber(num);
        }

        // 累加结果
        result += num;
        token = strtok(NULL, "+");  // 获取下一个加数
    }

    // 输出结果
    printf("%d\n", result);
    return 0;
}

1.4 知识点

a. strtok 分割字符串

功能strtok 是 C 标准库中的字符串处理函数,用于将字符串按指定分隔符分割为多个部分。

用法

char str[] = "123+3456L2+789R4+502S";
char *token = strtok(str, "+");  // 第一次分割,使用 "+" 作为分隔符
while (token != NULL) {
    printf("分割部分:%s\n", token);
    token = strtok(NULL, "+");  // 获取下一个分割部分
}

输出

分割部分:123
分割部分:3456L2
分割部分:789R4
分割部分:502S

注意

  • 第一次调用 strtok 需要传入目标字符串;后续调用传入 NULL 以继续分割。
  • 原字符串会被修改(分隔符替换为 \0)。

b. sscanf 提取数据与后缀

功能sscanf 是从字符串中提取数据的函数。格式化字符串 "%d%[LR0123456789S]" 用于提取数字和后缀部分。

用法

char token[] = "3456L2";
int num;
char suffix[10];

sscanf(token, "%d%[LR0123456789S]", &num, suffix);
printf("数字部分:%d\n", num);
printf("后缀部分:%s\n", suffix);

输出

数字部分:3456
后缀部分:L2

解释

  • %d:匹配整数并存储到 num
  • %[LR0123456789S]:匹配后缀中允许的字符集,并存储到 suffix
  • 后缀可为空,例如对于 123,只会提取数字,suffix 为空字符串。
c. 左右移动
  • 左移公式:rotated[i] = str[(i + times) % len]
  • 右移公式:rotated[(i + times) % len] = str[i]
  • 使用 % len 确保移位次数不超过字符串长度。