[R37A]电话簿


数据规模:1≤n≤10001 \le n \le 1000,1≤∣si∣≤1001 \leq |s_i| \leq 100。sis_i 由小写英文字母和数字组成。

思路

按题意对每个字符串逐字符转译:若字符是数字 xx(0≤x≤90 \le x \le 9),替换为第 x+1x+1 个大写英文字母;若是小写字母则原样保留。

由于题目保证输入只含 ASCII 小写字母和数字(均为单字节),可直接按字节处理。数字 '0' 的 ASCII 值是 4848,'9' 是 5757;大写字母 'A' 的 ASCII 值是 6565。映射关系即为 digit_byte + 17(因为 48+17=6548 + 17 = 65),或更直观地写作 'A' + (digit_byte - '0'),对应 0→A,1→B,…,9→J0 \rightarrow A, 1 \rightarrow B, \dots, 9 \rightarrow J。

小写字母(ASCII 97∼12297 \sim 122)不在数字区间内,保持原字节即可。把每个字节处理后收集到 Array<UInt8> 中,最后用 String.fromUtf8 一次性构造结果字符串。

复杂度

时间 O(∑∣si∣)O\left(\sum |s_i|\right),空间 O(max⁡∣si∣)O(\max |s_i|)。每个字符仅做一次比较和可能的加减法,远低于限制。

仓颉实现

查看仓颉实现
import std.console.*
import std.convert.*

main() {
    let reader = Console.stdIn
    let n = Int64.parse(reader.readln().getOrThrow())
    for (_ in 0..n) {
        let s = reader.readln().getOrThrow()
        let bytes = Array<UInt8>(s.size, { i: Int64 =>
            let ch = s[i]
            if (ch >= 0x30u8 && ch <= 0x39u8) {
                // '0'=48, '9'=57: digit x -> 'A' + (x), since '0'->'A', so 'A'(65) + (ch - 48)
                0x41u8 + (ch - 0x30u8)
            } else {
                ch
            }
        })
        println(String.fromUtf8(bytes))
    }
}