#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。