字符分身

解题思路

这道题目要求我们对于每一个可能的特殊字符(a-z),模拟字符串的破译过程,并找出破译后字符串的第K个字符。如果破译后的字符串长度小于K,则输出'*'。

关键点分析

  1. 特殊字符的作用:当遇到连续x个特殊字符时,会将后面x个字符(或剩余所有字符)复制x次。

  2. 破译过程:我们需要模拟字符串的破译过程,计算在每种特殊字符情况下,字符串如何被扩展。

  3. 高效计算:由于n和K可能很大(1e6和1e9),我们需要避免实际构建整个破译后的字符串,而是通过数学计算来确定第K个字符。

代码注释

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n, k;
string s, tmp, ans(26,'*'); // ans初始化为26个'*',对应a-z的结果

int main(){
    cin>>n>>k;
    cin>>s;
    // 对每个可能的特殊字符(a-z)进行处理
    for(char ch='a'; ch<='z'; ch++){ 
        ll lens = 0;  // 当前已处理的字符长度
        bool found = 0; // 标记是否找到第K个字符

        // 遍历原字符串
        for(int i=0;i<n;){
            // 当前字符不是特殊字符
            if(s[i] != ch){
                lens++;
                // 如果当前长度已经达到K,记录结果并跳出循环
                if(lens >= k){
                    ans[ch-'a'] = s[i];
                    found = 1;
                    break;
                } 
                i++;
                continue;	
            }
            
            // 当前字符是特殊字符,计算连续出现的次数cnt
            int cnt = 0;
            while(i<n && s[i]==ch){
                cnt++; i++;
            }
            
            // 计算可以复制的字符数量(取min(cnt, 剩余字符数))
            int copy_lens = min(cnt, n-i);
            string copy_str = s.substr(i,copy_lens);
            i += copy_lens; 
            
            // 计算复制后的总增加长度:copy_str.size() * cnt
            ll add_lens = copy_str.size() * cnt;
            // 如果加上这部分长度后超过K,计算第K个字符的位置
            if(lens + add_lens >= k){
                ll pos = k - lens - 1; // 转换为0-based索引
                ans[ch-'a'] = copy_str[ pos % copy_str.size() ];
                found = 1; 
                break;
            } 
            lens += add_lens;
        } 
    }
    cout<<ans;
    return 0;
}

算法思路

  1. 初始化结果数组ans:初始时所有字符的结果都是'*',表示默认情况下破译后的字符串长度不足K。

  2. 遍历每个可能的特殊字符(a-z)

    • 初始化当前长度lens:记录在破译过程中已经处理的字符数量。
    • 遍历原字符串s
      • 遇到非特殊字符:直接增加lens,并检查是否达到K。
      • 遇到特殊字符:计算连续出现的次数cnt,然后复制后面min(cnt,剩余字符数)的字符cnt次。计算这部分复制后的总长度,并检查是否覆盖了第K个字符。
        • 如果覆盖了第K个字符,则通过数学计算确定该字符在复制字符串中的位置。
        • 如果没有覆盖,则继续处理后续字符。
  3. 输出结果:对于每个特殊字符,输出对应的第K个字符或'*'。

这种方法避免了实际构建整个破译后的字符串,而是通过数学计算高效地确定第K个字符的位置,适用于大规模数据。

posted @ 2025-05-09 17:26  季风起  阅读(2)  评论(0)    收藏  举报