【洛谷P1383 高级打字机】

题目描述

早苗入手了最新的高级打字机。最新款自然有着与以往不同的功能,那就是它具备撤销功能,厉害吧。

请为这种高级打字机设计一个程序,支持如下3种操作:

1.T x:在文章末尾打下一个小写字母x。(type操作)

2.U x:撤销最后的x次修改操作。(Undo操作)

(注意Query操作并不算修改操作)

3.Q x:询问当前文章中第x个字母并输出。(Query操作)

文章一开始可以视为空串。

输入输出格式

输入格式:

第1行:一个整数n,表示操作数量。

以下n行,每行一个命令。保证输入的命令合法。

输出格式:

每行输出一个字母,表示Query操作的答案。

输入输出样例

输入样例#1:  复制
7
T a
T b
T c
Q 2
U 2
T c
Q 2
输出样例#1:  复制
b
c

说明

【数据范围】

对于40%的数据 n<=200;

对于100%的数据 n<=100000;保证Undo操作不会撤销Undo操作。

<高级挑战>

对于200%的数据 n<=100000;Undo操作可以撤销Undo操作。

必须使用在线算法完成该题。

生硬的讲解

这题我一看就不会,所以直接运用数组强行模拟栈,轻松拿下50Pts(然后就开始使劲颓废

那么我们就先来讲一讲50Pts是如何拿下的吧QwQ

首先,看到这个题(前100%的数据点),果断想到了栈(这前100%和栈完全一样啊QwQ)

直接模拟

#include
#include
#include
#include
#include
#include<string>
#include
#include
#include
#include
using namespace std;
#define maxn 100001
int top,t;
char st[maxn];
int main() 
{
    freopen("type.in","r",stdin);
    freopen("type.out","w",stdout);
    scanf("%d",&t);
    while(t--)
    {
        char c1[2],c2[2];
        int x;
        scanf("%s",c1);
        if(c1[0]=='T')
        {
            scanf("%s",c2);
            st[++top]=c2[0];
        }
        if(c1[0]=='U')
        {
            scanf("%d",&x);
            top-=x;
        }
        if(c1[0]=='Q')
        {
            scanf("%d",&x);
            printf("%c\n",st[x]);
        }
    }
    return 0;
}

那么就行这样吧

(然而并没有完(Van~))

讲一下wz小姐姐坠强的分块正解吧(能力有限,只能就着代码硬干)

#include 
#include 
#include 
template <class T>
inline void read(T &num) { //这个快读就比较硬核
    bool flag = 0;
    num = 0;
    char c = getchar();
    while ((c < '0' || c > '9') && c != '-')
        c = getchar();
    if (c == '-') {
        flag = 1;
        c = getchar();
    }
    num = c - '0';
    c = getchar();
    while (c >= '0' && c <= '9')
        num = (num << 3) + (num << 1) + c - '0', c = getchar();
    if (flag)
        num *= -1;
}
inline void read(char &c) {//读字符专用读取 
    do {
        c = getchar();
    } while (c == ' ' || c == '\n' || c == '\r');
}
template <class T>
inline void output(T num) {
    if (num < 0) {
        putchar('-');
        num = -num;
    }
    if (num >= 10)
        output(num / 10);
    putchar(num % 10 + '0');
}
template <class T>
inline void outln(T num) {
    output(num);
    putchar('\n');
}
template <class T>
inline void outps(T num) {
    output(num);
    putchar(' ');
}
template <class T>
inline T max(T a, T b) {
    return a < b ? b : a;
}
const int N = 100000;
int n, B;
struct node {
    char *s;
    int now, pc;
    node *pre;
    node() {
        now = pc = 0;
        s = new char[B];
        pre = NULL;
    }
    void copy(node *src) {
        now = src->now;
        pc = src->pc;
        pre = src->pre;
        for (int i = 0; i < now; i++) {
            s[i] = src->s[i];
        }
    }
} * head[N];
int lst;
void append(char x) {
    if (head[lst]->now == B) {
        head[++lst] = new node;
        head[lst]->pre = head[lst - 1];
        head[lst]->pc = head[lst - 1]->pc + 1;
        head[lst]->s[head[lst]->now++] = x;
    } else {
        head[++lst] = new node;
        head[lst]->copy(head[lst - 1]);
        head[lst]->s[head[lst]->now++] = x;
    }
}
char query(int x) {
    int siz = head[lst]->now + head[lst]->pc * B;
    x = siz - x + 1;
    if (x <= head[lst]->now) {
        return head[lst]->s[head[lst]->now - x];
    }
    x -= head[lst]->now;
    node *now = head[lst]->pre;
    while (x > B) {
        now = now->pre;
        x -= B;
    }
    return now->s[B - x];
}
int main() {
    read(n);
    B = sqrt(n);
    head[0] = new node;
    for (int i = 1; i <= n; i++) {
        char op;
        read(op);
        if (op == 'T') {
            char x;
            read(x);
            append(x);
        }
        if (op == 'U') {
            int x;
            read(x);
            head[lst + 1] = head[lst - x];
            lst += 1;
        }
        if (op == 'Q') {
            int x;
            read(x);
            putchar(query(x));
            putchar('\n');
        }
    }
}

大概就是这样,具体的我也不是很清楚,感性理解一下吧

转载于:https://www.cnblogs.com/gongcheng456/p/11166552.html

你可能感兴趣的:(【洛谷P1383 高级打字机】)