#P2669. 第1题-字符串解密
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 310
            Accepted: 65
            Difficulty: 4
            
          
          
          
                       所属公司 : 
                              美团
                                
            
                        
              时间 :2025年3月8日-开发岗
                              
                      
          
 
- 
                        算法标签>模拟          
 
第1题-字符串解密
题解
题目描述
小美有一个加密字符串,解密过程如下:
初始时,解密字符串 t 为空,记录位移的整数 p 为 0。依次处理每个字符:
- 若当前字符是数字 
x,更新p:若p为 0,则置为x;否则p左移一位后加上x。 - 若当前字符非数字,先对 
t左移p位(将前p位移至末尾),p置 0,再处理字符:若为R则反转t,否则添加到t末尾。 
思路
- 模拟过程:遍历每个字符,根据类型执行不同操作。
 - 数字处理:维护 
p的值,处理多位数拼接。 - 左移操作:对当前字符串 
t左移p % len(t)位(处理大数取模)。 - 反转或添加字符:根据字符类型反转或追加。
 
代码分析(C++)
- 数字处理:逐位构建 
p的值。 - 左移操作:使用 
substr分割字符串并拼接。 - 反转或追加:直接使用 
reverse或push_back。 
问题本质
模拟题,严格按照步骤处理每个字符,注意字符串操作和状态维护。
cpp
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
    int T; // 测试数据组数
    cin >> T;
    while (T--) {
        string s, t; // s 是加密字符串,t 是解密后的字符串
        int p = 0;  // 记录位移的整数 p
        cin >> s;
        for (char c : s) { // 遍历加密字符串的每个字符
            if (isdigit(c)) { // 如果当前字符是数字
                int x = c - '0'; // 将字符转换为数字
                p = (p == 0) ? x : p * 10 + x; // 更新 p 的值
            } else { // 如果当前字符不是数字
                int len = t.size(); // 获取当前 t 的长度
                if (len > 0) { // 如果 t 不为空
                    int shift = p % len; // 计算左移的位数
                    t = t.substr(shift) + t.substr(0, shift); // 左移 p 位
                }
                p = 0; // 重置 p
                if (c == 'R') { // 如果字符是 'R'
                    reverse(t.begin(), t.end()); // 反转字符串 t
                } else {
                    t.push_back(c); // 否则将字符添加到 t 的末尾
                }
            }
        }
        cout << t << endl; // 输出解密后的字符串
    }
    return 0;
}
python
T = int(input())  # 测试数据组数
for _ in range(T):
    s = input().strip()  # 输入加密字符串
    t = []  # 解密后的字符串
    p = 0  # 记录位移的整数 p
    for c in s:  # 遍历加密字符串的每个字符
        if c.isdigit():  # 如果当前字符是数字
            x = int(c)  # 将字符转换为数字
            p = x if p == 0 else p * 10 + x  # 更新 p 的值
        else:  # 如果当前字符不是数字
            if t:  # 如果 t 不为空
                shift = p % len(t)  # 计算左移的位数
                t = t[shift:] + t[:shift]  # 左移 p 位
            p = 0  # 重置 p
            if c == 'R':  # 如果字符是 'R'
                t.reverse()  # 反转字符串 t
            else:
                t.append(c)  # 否则将字符添加到 t 的末尾
    print(''.join(t))  # 输出解密后的字符串
java
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt(); // 测试数据组数
        scanner.nextLine(); // 读取换行符
        while (T-- > 0) {
            String s = scanner.nextLine(); // 输入加密字符串
            List<Character> t = new ArrayList<>(); // 解密后的字符串
            int p = 0; // 记录位移的整数 p
            for (char c : s.toCharArray()) { // 遍历加密字符串的每个字符
                if (Character.isDigit(c)) { // 如果当前字符是数字
                    int x = c - '0'; // 将字符转换为数字
                    p = (p == 0) ? x : p * 10 + x; // 更新 p 的值
                } else { // 如果当前字符不是数字
                    int len = t.size(); // 获取当前 t 的长度
                    if (len > 0) { // 如果 t 不为空
                        int shift = p % len; // 计算左移的位数
                        List<Character> shifted = new ArrayList<>(t.subList(shift, len)); // 截取后半部分
                        shifted.addAll(t.subList(0, shift)); // 添加前半部分
                        t = shifted; // 更新 t
                    }
                    p = 0; // 重置 p
                    if (c == 'R') { // 如果字符是 'R'
                        Collections.reverse(t); // 反转字符串 t
                    } else {
                        t.add(c); // 否则将字符添加到 t 的末尾
                    }
                }
            }
            StringBuilder sb = new StringBuilder(); // 用于拼接字符
            for (char ch : t) sb.append(ch); // 将列表转换为字符串
            System.out.println(sb); // 输出解密后的字符串
        }
        scanner.close(); // 关闭输入流
    }
}
        题目内容
小美有一个加密的字符串s,你无意之间得到了他的加密方式,尝试解开它吧!
初始时,解密字符串t为空,除此之外,还有一个记录位移的整数p为0。依次对每一个i=1,2,...,∣s∣
进行以下操作(其中∣s∣代表字符串s的长度)
●如果s的第i个字符为数字x,则需要对p修改,具体地:
若p=0,则将p置为x(即p→x);
若p=0,则将p中的数字全部向高位移动一位,随后将空出来的个位填上x(即p→10p+x)
●如果s的第i个字符不为数字,则需要先将字符串左移p位 (即t1t2...tptp+1...t∣t∣→tp+1...t∣t∣t1t2...tp) ,随后将p重新置为0,再对t修改,具体地:
若字符为R,则反转字符串t;
若字符不为R,则直接将这个字符添加到字符串t的结尾;
请你直接输出解密完成后的字符串t。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数T(1≦T≦10)代表数据组数,每组测试数据描述如下:
在一行上输入一个长度为∣s∣(1≦∣8∣≤103),且由大小写字母和数字混合构成的字符串s代表小美的加密串。
输出描述
对于每一组测试数据,在一行上输出一个字符串,代表解密完成后的字符串。
样例1
输入
2
meRD2o
D0ame3
输出
Demo
Dame
说明
在第一组测试数据中:
- 第一步,将m加入,t="m";
 - 第二步,将e加入,t="me";
 - 第三步,翻转字符串,t= "em";
 - 第四步,将D加入,t="emD";
 - 第五步,p=2;
 - 第六步,先左移p位,t="Dem"; 再将o加入,t="Demo".