【做题笔记】UVA11988破损的键盘

本题可以在洛谷评测,但需要绑定账号

首先解释一下:Home键的作用是把光标移动,End键的作用是返回上次按Home键的地方

考虑朴素做法:输入为[时下一次插入在数组最前端,然后元素整体向后;同时令 last 变量记录上次离开的位置。如果输入为 ] 则令 当前光标 = last。

时间复杂度 (mathcal{O(} ext{TLE})) (大雾)

考虑链表的做法。设字符串为 (s),设 (nxt_i) 表示 (s_i) 右边的位置(即 (i+1) )。那么假装屏幕最左边有一个虚拟字符 0 ,那么初始化 (nxt_0=0) ,然后如果输入为 [ 则令当前鼠标位置 (cur=0) ,如果输入为 ] ,则令 (cur =) 上一次离开的位置 (last) 。如果是正常字符,则更改链表 (nxt_i)(nxt_{cur}) 的值,然后如果当前光标等于上一次离开的位置,则更新 (last) ,然后更新 cur 。具体见参考代码。

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

char s[100000001];
int cur,last,nxt[1000001];

int main()
{
    while(cin>>s+1)
    {
        int len=strlen(s+1);
        cur=last=0;
        nxt[0]=0;
        
        for(int i=1;i<=len;i++)
        {
            if(s[i]=='[') cur=0;
            else if(s[i]==']') cur=last;
            else
            {
                nxt[i]=nxt[cur]; //当前字符的右边是当前光标的右边
                nxt[cur]=i; //当前光标的右边是当前字符所在的位置
                if(cur==last) last=i; //更新last
                cur=i; //更新cur
            }
        }

        for(int i=nxt[0];i;i=nxt[i]) //遍历链表,相当于每次“跳”到当前链表位置的右边在数组中的位置
            cout<<s[i];
        puts("");

    }

    return 0;
}

能过。

原文地址:https://www.cnblogs.com/BlueInRed/p/12367603.html