题解:P12281 [蓝桥杯 2024 国 Python A/Java A] 记事本

· · 题解

思路

模拟方式

模拟罢了,但是如何实现光标?考虑使用两个栈 aba 表示光标左侧的文字,b 表示光标右侧的文字(如下图)。

操作判断

这里反而是最简单的。

光标移动的判断

判断读入的字符串第一位是不是数字即可,至于往左和往右看最后一位。

获取 n 的方式很简单,从第一位遍历到倒数第二位(最后一位是方向)用一个初始为 0 的变量 t,每次乘以 10 在加上当前字符,就能实现增加位数。

int t=0;
for(int i=0;i<s.size()-1;i++) t=t*10+(s[i]-'0');

在移动过程中,每移动一位就要将对应方向的栈顶字符插入到另一个栈中(如下图)。

if(s[s.size()-1]=='h'){
    while(t--&&!a.empty()){
        b.push(a.top());
        a.pop();
    }
}
else{
    while(t--&&!b.empty()){
        a.push(b.top());
        b.pop();
    }
}

删除字符的判断

看第一位和最后一位,大同小异,只是获取 n 要从第二位开始。删除字符的方式也很简单,根据方向把对应的栈的栈顶弹出即可。

if(s[s.size()-1]=='h') while(t--&&!a.empty()) a.pop();
else while(t--&&!b.empty()) b.pop();

插入字符串

由于插入字符串是统一在光标左侧,所以只需要插入在 a 栈即可。

for(int i=8;i<s.size()-1;i++) a.push(s[i]);

输出

现将 a 栈的所有字符转移到 b 栈,最后遍历 b 栈即可。

代码

#include<iostream>
#include<stack>
using namespace std;
stack<char>a,b;
int main()
{
    int T;
    cin>>T;
    string s;
    getline(cin,s);
    while(T--){
        getline(cin,s);
        if(s[0]>='0'&&s[0]<='9'){
            int t=0;
            for(int i=0;i<s.size()-1;i++) t=t*10+(s[i]-'0');
            if(s[s.size()-1]=='h'){
                while(t--&&!a.empty()){
                    b.push(a.top());
                    a.pop();
                }
            }
            else{
                while(t--&&!b.empty()){
                    a.push(b.top());
                    b.pop();
                }
            }
        }
        else if(s[0]=='d'){
            int t=0;
            for(int i=1;i<s.size()-1;i++) t=t*10+(s[i]-'0');
            if(s[s.size()-1]=='h') while(t--&&!a.empty()) a.pop();
            else while(t--&&!b.empty()) b.pop();
        }
        else{
            for(int i=8;i<s.size()-1;i++) a.push(s[i]);
        }
    }
    while(!a.empty()){
        b.push(a.top());
        a.pop();
    }
    while(!b.empty()){
        cout<<b.top();
        b.pop();
    }
    return 0;
}