小L的编辑器

https://ac.nowcoder.com/acm/contest/11164/C

题目描述

小 L 发明了一个文本编辑器,由于小 L 非常垃圾,所以写出的文本编辑器也很垃圾。 该文本编辑器的运行方式大概是这样的:一开始文本为空,有一个光标在开头,每一次小 L 会输入一个字符,该字符就会被插入到光标的位置上,然后光标会随机地停留在该字符的左边或右边。 现在小 L 用这个文本编辑器打了一大段文字,但他却忘了保存了,他只记得他依次打了哪些字符和打完每个字符后光标停在了该字符的左边还是右边,你能帮助他还原出最终文本的内容吗?

输入描述:
输入文件有两行,第一行为一个字符串s,第二行为一个字符串t。
s, t 的长度相同,s 为一个仅包含小写字母的字符串,t 为一个仅包含’L’, ‘R’ 的字符串。分别表示小 L 依次打了哪些字符,和每打完一个字符后光标停在了字符的左边还是右边( ‘L’ 为左边,‘R’ 为右边)。
输出描述:
输出仅一行一个字符串,为最终文本的内容。
示例1

输入

abcde
LLRLR

输出

cedba

说明

在每一时刻文本编辑器的状态如下("|"表示光标的位置):
|a
|ba
c|ba
c|dba
ce|dba
设 n 为 s, t 的长度。
对于 30%30% 的数据,满足n≤1000。
另有 20%20% 的数据,满足存在一个 x 使得x < n,t_0 = t_1 = …t_x = ‘R’, t_{x + 1} = … = t_{n - 1} = 'L’0≤x<n。
对于 100% 的数据,满足 1≤n≤1,000,000。

一、模拟链表

在这里插入图片描述

#include<iostream>
using namespace std;
struct node{
    int r,l;
};
const int maxn = 1e6+5;
node res[maxn];
int main()
{
    string s,t;
    cin>>s>>t;
    
    for(int i=0;i<=s.length();i++){
        res[i].l = -1,res[i].r = maxn;
    }
    for(int i=0;i<s.length()-1;i++){
        if(t[i] == 'L'){
            if(res[i].l != -1) res[res[i].l].r = i+1;
            res[i+1].l = res[i].l;
            res[i].l = i+1;
            res[i+1].r = i;
        }else{
            if(res[i].r != maxn) res[res[i].r].l = i+1;
            res[i+1].r = res[i].r;
            res[i+1].l = i;
            res[i].r = i+1;
        }
    }
    int first = -1;
    for(int i=0;i<s.length();i++){
        if(res[i].l == -1){
            first = i;
            break;
        } 
    }
    int final = first;
    while(res[final].r != maxn){
        cout<<s[final];
        final = res[final].r;
    }
    cout<<s[final]<<endl;
}

二、前后缀
转自https://blog.nowcoder.net/n/28aa5a550c0841c7831eb4b8f30057ed?f=comment

发现每次操作完之后,光标前的字符串就永远是这个字符串的前缀了,光标后永远是这个字符串的后缀了。

因为无论光标在当前字母的左边还是右边,都不可能影响到上一个字符和上上个字符之间的东西(后缀同理)。

所以开两个 string 记一下当前光标前的字符串和光标后的字符串。

发现光标后的字符串需要从前面插入字符,string好像不支持,就从后插入,最后再反过来。

#include <iostream>
#include <algorithm>
using namespace std;
string a,b,x,y;//x后缀,y前缀
int main() {
    cin >> a >> b;
    int n=a.size();
    for(int i=0;i<n;i++)
    {
        if(b[i]=='L') x+=a[i];//放到左边相当于后缀多了个a[i]
        else y+=a[i];//右边相当于前缀多了个a[i]
    }
    reverse(x.begin(),x.end());//后缀要反过来
    cout << y << x;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值