#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".