文本编辑器 Editor

文本编辑器


题意描述

九发明了一个完美的文本编辑器。这个编辑器拥有两个光标(cursor),所以九能够同时在两处地方插入和删除文本。这个编辑器除了正常的编辑功能以外,还有一些只有九才知道用处的功能,例如翻转两个光标之间的文本。某一天,九把自己的完美文本编辑器给弄丢了,但是她还有好多好多文本需要处理。于是她想请聪明又智慧的你帮她实现完美文本编辑器的一些功能。
功能列表如下:

功能名称 命令格式 说明
< (move left) < w w 为一个字符,“L”或“R”,表示左光标还是右光标(下同)。该命令将选定光标向左移动,如果已经是最左端则不移动。命令执行成功时输出“T”,若光标已经在最左端,则输出“F”。
> (move right) > w w 同上。与< 命令不同的是,该命令将光标向右移动。命令执行成功时输出“T”,若光标已经在最右端,则输出“F”。
I (insert) I w c w 同上。c 是一个可见字符(33≤ ascii 码 ≤ 126),代表在该光标左侧插入该字符。该命令始终输出“T”。
D (delete) D w w 同上。代表删除该光标右侧的一个字符。命令执行成功时输出“T”,若光标右侧没有字符输出“F”。
R (reverse) R 代表翻转左光标和右光标之间的字符。该命令只有左光标在右光标左侧时才能执行。(两光标重合时也不能执行)命令执行成功时输出“T”,否则输“F”。
S (show) S 代表显示当前处理的文本。该命令只输出文本,不输出“T”和“F”。

开始时文本编辑器中有一定内容,左光标在第一个字符左,右光标在最后一个字符右。

注意:在插入和删除操作中,没有被操作的光标与文本的相对左右位置保持不变。特别地,若两个光标重叠,操作后也仍然重叠。

输入格式

第一行是初始时文本编辑器内容。

第二行是一个正整数 N,N 表示操作次数。

接下来有 N 行,每行有一个命令,命令格式如上方表格。

输出格式

对于每个命令,按上方表格要求执行并输出。

样例输入

goodykc
11
I R u
I R l
> L
> L
> L
> L
R
D R
< R
D R
S

样例输出

T
T
T
T
T
T
T
F
T
T
goodluck

样例解释

[goodykc]
[goodykcu]
[goodykcul]
g[oodykcul]
go[odykcul]
goo[dykcul]
good[ykcul]
good[lucky]
good[lucky](光标右边没有字符,失败删除)
good[luck]y
good[luck]
goodluck

数据规模与约定

  • 对于 40% 的数据:1 ≤ N , 初始文本长度 ≤ 100,数据不包含翻转(Reverse)操作;
  • 另有 30% 的数据:1 ≤ N , 初始文本长度 ≤ 105,数据不包含翻转(Reverse)操作;
  • 另有 20% 的数据:1 ≤ N , 初始文本长度 ≤ 105,数据包含翻转(Reverse)操作;
  • 对于 100% 的数据:1 ≤ N , 初始文本长度 ≤ 4 × 106,输出文件大小 ≤ 20MB;

这道题最后3个点难度很大,但是前7个点应该是非常容易通过的,然而我只过了三个,一个原因是对这种代码量大的题速度跟不上,还有写链表的时候没有将头指针的pre赋为-1,以后写链表的时候一定要注意。

后面3个点的解法还没看懂,以后再说
更新:其实就是个平衡树区间翻转,现在感觉当时的我好 zz 啊


70分代码

#include
#include
#include
using namespace std;

const int MAXL=1e5;
int N;
char s[MAXL+10];
int len;

int tcnt;
struct T{int pre,next;char c;} text[MAXL*11+10];
void del(int x)
{
    text[text[x].pre].next=text[x].next;
    text[text[x].next].pre=text[x].pre;
    text[0].pre=-1;
}
void add(int x,char c)
{
    ++tcnt;
    text[tcnt].pre=x;
    text[tcnt].next=text[x].next;
    text[text[x].next].pre=tcnt;
    text[x].next=tcnt;
    text[tcnt].c=c;
    text[0].pre=-1;
}

struct C
{
    int pos;
    void pri(bool t){printf("%s\n",t?"T":"F");}
    void move(bool l)
    {
        if(l)
        {
            if(text[pos].pre!=-1)
            {
                pos=text[pos].pre;
                pri(true);
            }else pri(false);
        }else 
            if(text[pos].next)
            {
                pos=text[pos].next;
                pri(true);
            }else pri(false);
    }
    void insert(char c)
    {
        add(pos,c);
        pos=text[pos].next;
        pri(true);
    }
    void rm()
    {
            if(text[pos].next)
            {
                del(text[pos].next);
                pri(true);
            }else pri(false);
    }

} L,R;

int main()
{
    freopen("editor.in","r",stdin);
    freopen("editor.out","w",stdout);
    int i;
    scanf("%s",&s);
    len=strlen(s);
    for(i=0;i0,R.pos=len;

    scanf("%d",&N);
    while(N--)
    {
        char c;
        do c=getchar(); 
        while(c<33||c>126);
        if(c=='<'||c=='>') 
        {
            bool left=c=='<'?1:0;
            do c=getchar(); while(c<33||c>126);
            if(c=='L') L.move(left);
            else R.move(left);
        }else if(c=='I')
        {
            do c=getchar(); while(c<33||c>126);
            if(c=='L')
            {
                do c=getchar(); while(c<33||c>126);
                L.insert(c);
            }else 
            {
                do c=getchar(); while(c<33||c>126);
                R.insert(c);
            }
        }else if(c=='D')
        {
            do c=getchar(); while(c<33||c>126);
            if(c=='L') L.rm();
            else R.rm();
        }else if(c=='S')
        {
            for(i=text[0].next;i;i=text[i].next)
                putchar(text[i].c);
            printf("\n");
        }
    }
    return 0;
}

100分标程

#include 
#include 
#include 
#include 

using namespace std;
#define N 10000000
int pre[N], suf[N];
char ch[N], st[N];
int idx, pos[2], cnt[2];

inline void swap(int &a, int &b) {
    int c = a;
    a = b;
    b = c;
}

void Insert(int opt, char c) {
    ++idx;
    ch[idx] = c;
    int u = pos[opt], v = suf[u];
    pre[idx] = u; suf[idx] = v;
    suf[u] = idx; pre[v] = idx;
    if (cnt[opt^1] >= cnt[opt]) cnt[opt^1]++;
    pos[opt] = idx; cnt[opt]++;
    if (pos[opt^1] == u) pos[opt^1] = idx;
    puts("T");
}

void LMove(int opt) {
    if (pos[opt] == 1) {
        puts("F");
        return ;
    }
    int u = pos[opt], v = pre[u];
    if (suf[v] != u) swap(suf[v], pre[v]);
    pos[opt] = v; cnt[opt]--;
    puts("T");
} 

void RMove(int opt) {
    if (suf[pos[opt]] == 2) {
        puts("F");
        return ;
    }
    int u = suf[pos[opt]], v = suf[u];
    if (pre[v] != u) swap(suf[v], pre[v]);
    pos[opt] = u; cnt[opt]++;
    puts("T");  
}

void Delete(int opt) {
    if (suf[pos[opt]] == 2) {
        puts("F");
        return ;
    }
    int u = pos[opt], v = suf[u], w = suf[v];
    if (pre[w] != v) swap(suf[w], pre[w]);
    if (cnt[opt^1] > cnt[opt]) cnt[opt^1]--;
    if (pos[opt^1] == v) pos[opt^1] = u;
    suf[u] = w; pre[w] = u;
    puts("T");
}

void Reverse() {
    if (cnt[1] - cnt[0] <= 0) {
        puts("F");
        return ;
    }
    if (cnt[1] - cnt[0] == 1) {
        puts("T");
        return ;
    }
    int a = pos[0], b = suf[a], c = pos[1], d = suf[c];
    swap(pre[b], suf[b]); swap(pre[c], suf[c]);
    suf[a] = c; pre[c] = a; suf[b] = d; pre[d] = b;
    pos[1] = b;
    puts("T");
}

void Show() {
    int u = 1;
    while (true) {
        if (pre[suf[u]] != u) swap(pre[suf[u]], suf[suf[u]]);
        u = suf[u];
        if (u == 2) break;
        putchar(ch[u]);
    }
    putchar('\n');
}

void Build() {
    scanf("%s",st);
    idx = 2;
    pre[1] = -1; suf[1] = 2;
    pre[2] = 1; suf[2] = -1;
    pos[0] = pos[1] = cnt[0] = cnt[1] = 1;
    int len = strlen(st);
    for (int i = 0; i < len; i++) {
        ++idx;
        ch[idx] = st[i];
        pre[idx] = i == 0 ? 1 : idx - 1;
        suf[idx] = i == len - 1 ? 2 : idx + 1;
    }
    if (len > 0) {
        suf[1] = 3; pre[2] = idx; 
        pos[1] = idx; cnt[1] = len + 1;
    } 
}

inline int Dir() {
    getchar();
    return getchar() == 'L' ? 0 : 1;
}

int main() {
    freopen("editor.in", "r", stdin);
    freopen("editor.out", "w", stdout);
    Build();
    int m;
    scanf("%d",&m);
    for (int i = 1; i <= m; i++) {
        getchar(); 
        char opt = getchar();
        while (opt != '<' && opt != '>' && !(opt >= 'A' && opt <= 'Z')) opt = getchar(); 
        if (opt == '<') LMove(Dir());
        else if (opt == '>') RMove(Dir());
        else if (opt == 'I') {
            int d = Dir();
            char c = ' ';
            while (c < 33 || c > 126) c = getchar();
            Insert(d, c);
        }
        else if (opt == 'D') Delete(Dir());
        else if (opt == 'R') Reverse();
        else if (opt == 'S') Show();
    }
    return 0;
}

你可能感兴趣的:(题解,-联赛)