#P2725. 第1题-游游的字符串
-
1000ms
Tried: 58
Accepted: 14
Difficulty: 2
所属公司 :
阿里
时间 :2025年3月22日-阿里淘天(算法岗)
-
算法标签>模拟
第1题-游游的字符串
字符串对照试验
题解思路
这道题目要求对两个字符串 s 和 t 进行比较,根据每个字符的类型和等级输出对应的结果。具体操作如下:
步骤分析
-
字符分类与等级判断
每个字符有不同的等级,可以分为四类:- 可控一级:小写字母
a-z,其 ASCII 值在97-122之间。 - 可控二级:大写字母
A-Z,其 ASCII 值在65-90之间。 - 可控三级:数字
0-9,其 ASCII 值在48-57之间。 - 不可控字符:其他符号或字符,如空格、标点符号等。
对每个字符,我们需要判断其属于哪种类型,如果两个字符同时为可控字符,接下来的操作才有意义。
- 可控一级:小写字母
-
等级比较与输出
- 如果
s[i]和t[i]都是可控字符,且它们的等级相同,则输出它们 ASCII 值的中位字符(向上取整的平均值)。 - 如果
s[i]和t[i]都是可控字符,但它们的等级不同,则输出它们 ASCII 值的中位数(向上取整的平均值)。 - 如果
s[i]或t[i]不是可控字符,则直接输出下划线_。
- 如果
-
计算中位 ASCII 值
中位 ASCII 值定义为两个字符 ASCII 值的平均值向上取整,可以通过(a + b + 1) // 2来实现,其中a和b是字符的 ASCII 值。
算法流程
- 输入解析:首先读取输入的字符串长度
n和两个字符串s和t。 - 字符判断与操作:遍历每个字符,判断它们的类型并根据上述规则进行处理。
- 输出结果:输出最终的结果。
复杂度分析
- 时间复杂度:由于我们需要遍历每个字符并进行常数时间的处理,因此总体的时间复杂度是 O(n),其中 n 为字符串的长度。
- 空间复杂度:除了输入的字符串和结果字符串,所需额外空间是常数级别,因此空间复杂度为 O(1)。
代码实现
Python代码
def check(c):
# 判断字符类型
if c.islower():
return 1
elif c.isupper():
return 2
elif c.isdigit():
return 3
return 0
def solve(n, s, t):
result = []
for i in range(n):
if check(s[i]) > 0 and check(t[i]) > 0:
# 获取字符的ASCII值
a = ord(s[i])
b = ord(t[i])
# 确保a <= b
if a > b:
a, b = b, a
# 如果等级相同,输出字符,否则输出ASCII码
if check(s[i]) == check(t[i]):
mid_char = chr((a + b + 1) // 2)
result.append(mid_char)
else:
mid_ascii = (a + b + 1) // 2
result.append(str(mid_ascii))
else:
result.append('_')
return ''.join(result)
# 输入
n = int(input())
s = input()
t = input()
# 输出结果
print(solve(n, s, t))
Java代码
import java.util.*;
public class Main {
// 判断字符类型
public static int check(char c) {
if (Character.isLowerCase(c)) return 1;
if (Character.isUpperCase(c)) return 2;
if (Character.isDigit(c)) return 3;
return 0;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine(); // 吸收换行符
String s = scanner.nextLine();
String t = scanner.nextLine();
StringBuilder result = new StringBuilder();
for (int i = 0; i < n; i++) {
if (check(s.charAt(i)) > 0 && check(t.charAt(i)) > 0) {
int a = s.charAt(i);
int b = t.charAt(i);
// 保证 a <= b
if (a > b) {
int temp = a;
a = b;
b = temp;
}
// 如果等级相同,输出字符,否则输出 ASCII 值
if (check(s.charAt(i)) == check(t.charAt(i))) {
char midChar = (char) ((a + b + 1) / 2);
result.append(midChar);
} else {
result.append((a + b + 1) / 2);
}
} else {
result.append('_');
}
}
System.out.println(result.toString());
}
}
C++代码
#include <bits/stdc++.h>
using namespace std;
// 判断字符类型
int check(char c) {
if (islower(c)) return 1;
if (isupper(c)) return 2;
if (isdigit(c)) return 3;
return 0;
}
int main() {
int n;
cin >> n;
string s, t;
cin.ignore(); // 清除换行符
getline(cin, s);
getline(cin, t);
string result;
for (int i = 0; i < n; i++) {
if (check(s[i]) > 0 && check(t[i]) > 0) {
int a = int(s[i]);
int b = int(t[i]);
// 保证 a <= b
if (a > b) swap(a, b);
// 如果等级相同,输出字符,否则输出 ASCII 值
if (check(s[i]) == check(t[i])) {
result.push_back(char((a + b + 1) / 2));
} else {
result += to_string((a + b + 1) / 2);
}
} else {
result.push_back('_');
}
}
cout << result << endl;
return 0;
}
题目内容
游游正在进行字符串对照试验,他有一个长度为n 的字符串s和另一个长度同样为n的字符串 t,他先定义一个字符:可控一级,当其为小写字母;可控二级,当其为大写字母;可控三级,当其为数字;不可控,当其为其他字符。随后,他将依次对每一个i=1,2,...,n进行以下操作:
- 如果s和t的第i个字符同时为可控的,且等级相同,则输出这两个字符的中位Ascii 码对应的字符;
- 如果s和t的第i个字符同时为可控的,但等级不同,则输出这两个字符的中位 Ascii 码;
- 否则,直接输出一条下划线"_"。
在这里,记字符u,v的 Ascii 码为Pu,Pu,则它们的 中位Ascii码定义为Pu和Pu,的平 均值向上取整。例如,a和z的中位 Ascii 码为m;A和B的中位Ascii 码为 B。
如果你需要 Ascii码相关的帮助,请参阅下表。

输入描述
第一行输入一个整数n(1≦n≦3×105)代表字符串的长度。
第二行输入一个长度为n 的字符串s。
第三行输入一个长度为n的字符串 t。
除此之外,保证字符串由数字、大小写字母、空格及!?.+−∗/这七个常见半角符号混合构成。保证 字符串的首尾不为空格。
输出描述
在一行上输出一个字符串,代表操作过后的字符串。。
样例1
输入
9
ciaLlo!?
dAmE*+-/
输出
8485gl____
说明
对于第一个字符,两者同时为可控的,但等级分别为二级和一级,所以,直接输出中位Ascii码, 查表可得,67和100的平均值向上取整为84
对于第二个字符,两者同时为可控的,但等级分别为一级和二级,所以,直接输出中位Ascii码, 查表可得,105 和65的平均值向上取整为85。
对于第三个字符,两者同时为一级可控,所以,输出中位Ascii码对应的字符,查表可得,97和 109 的平均值向上取整为103,对应g。