#P2919. 第1题-小歪的字符串
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 37
            Accepted: 13
            Difficulty: 3
            
          
          
          
                       所属公司 : 
                              阿里
                                
            
                        
              时间 :2025年4月28日-阿里国际(算法岗)
                              
                      
          
 
- 
                        算法标签>模拟          
 
第1题-小歪的字符串
题目分析
给定一个长度为 n 的字符串 s(1≤n≤106),由大小写混合的英文字母构成。
小歪从第一个字符开始依次输入,每次输入一个字符时需要花费以下时间:
- 基础时间
- 如果该字符(不区分大小写)之前未出现过,需 500 毫秒;
 - 否则,需 100 毫秒。
 
 - 额外时间(与前一个字符比较)
- 若当前字符与前一个字符完全相同(区分大小写),额外 23 毫秒;
 - 若两字符不区分大小写在字母表中相邻(如 'a' 和 'b'),额外 44 毫秒。(不把 'a' 和 'z' 视为相邻)
 
 
输出小歪输入完整字符串所需的总时间。
解题思路
- 线性扫描
维护一个集合seen(或大小为 26 的布尔数组)记录已经出现过的字母(全部转换成小写)。 - 状态维护
prev保存前一个字符(用于计算额外时间);total累计总时间。
 - 算法性质
- 单次遍历,所有操作均为 O(1);
 - 时间复杂度 O(n),空间复杂度 O(1)(固定大小的辅助结构)。
 
 
复杂度分析
- 时间复杂度:遍历字符串一次,O(n)。
 - 空间复杂度:只用常数级的额外空间(记录是否出现过的 26 个字母),O(1)。
 
代码实现
Python
import sys
def main():
    s = sys.stdin.readline().strip()
    seen = set()           # 已输入过的字母(小写)
    prev = None            # 前一个字符
    total = 0              # 累计时间
    for c in s:
        lower = c.lower()
        # 基础时间
        if lower not in seen:
            total += 500
            seen.add(lower)
        else:
            total += 100
        # 额外时间
        if prev is not None:
            if c == prev:
                total += 23
            elif abs(ord(lower) - ord(prev.lower())) == 1:
                total += 44
        prev = c
    print(total)
if __name__ == "__main__":
    main()
Java
import java.io.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String s = in.readLine().trim();
        boolean[] seen = new boolean[26];  // 标记 a–z 是否输入过
        char prev = 0;                     // 前一个字符,0 表示无
        long total = 0;                    // 总时间
        for (char c : s.toCharArray()) {
            char lower = Character.toLowerCase(c);
            int idx = lower - 'a';
            // 基础时间
            if (!seen[idx]) {
                total += 500;
                seen[idx] = true;
            } else {
                total += 100;
            }
            // 额外时间
            if (prev != 0) {
                if (c == prev) {
                    total += 23;
                } else if (Math.abs(lower - Character.toLowerCase(prev)) == 1) {
                    total += 44;
                }
            }
            prev = c;
        }
        System.out.println(total);
    }
}
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string s;
    cin >> s;
    vector<bool> seen(26, false);  // 标记 a–z 是否输入过
    char prev = 0;                  // 前一个字符
    long long total = 0;            // 总时间
    for (char c : s) {
        char lower = tolower(c);
        int idx = lower - 'a';
        // 基础时间
        if (!seen[idx]) {
            total += 500;
            seen[idx] = true;
        } else {
            total += 100;
        }
        // 额外时间
        if (prev) {
            if (c == prev) {
                total += 23;
            } else if (abs(lower - tolower(prev)) == 1) {
                total += 44;
            }
        }
        prev = c;
    }
    cout << total << "\n";
    return 0;
}
        题目内容
小歪将使用键盘输入一个长度为 n,由大小写字母混合构成的字符串。他从第一个字符开始,输入每一个字符所需的时间如下:
- 
如果输入的字符是此前没有输入过的(不区分大小写,即如果输入过 ′A′,那么 ′a′ 也算作输入过),需要 500 毫秒;
 - 
否则,需要 100 毫秒;
 
除此之外,还有一些额外的限制:
- 
如果输入的字符与前一个字符完全相同(区分大小写)。额外需要 23 毫秒;
 - 
如果输入的字符与前一个字符在字母表中相邻(不区分大小写),额外需要 44 毫秒。
 
你需要计算并输出小歪输入这个字符串所需的总时间。
【注意事项】最基础的字母表中,我们认为 ′a′ 与 ′z′ 不相邻。
输入描述
在一行上输入一个长度为 1≤len(s)≤106,由大小写字母混合构成的字符串 s。
输出描述
输出一个整数,表示小歪输入这个字符串所需的总时间,
示例1
输入
aAb
输出
1144
说明
输入第一个字符 ′a′,由于此前没有输入过,需要 500 毫秒,没有额外时间;
输入第三个字符 ′A′,由于此前已经输入过 ′a′,所以需要 100 毫秒,没有额外时间。
输入第二个字符 ′b′,由于此前没有输入过,需要 500 毫秒,除此之外,′A′ 与 ′b′ 在字母表中相邻,所以额外需要 44 毫秒。
总时间为 500+100+500+44=1144 毫秒