Some people say that Leonardo was a great admirer of Johannes Gutenberg, the German blacksmith who invented movable-type printing, and that he paid homage by designing a machine called the crayfish scrivener — il gambero scrivano — a very simple typing device. It is somehow similar to a simple modern typewriter and accepts only two commands: one to type the next character and one to undo the most recent commands. The notable feature of the crayfish scrivener is that the undo command is extremely powerful: an undo is also considered to be a command itself, and can be undone.
Statement
Your task is to realize a software version of the crayfish scrivener: it starts with an empty text and accepts a sequence of commands entered by the user, and queries for specific positions of the current version of the text, as follows.
Init()
— called once at the beginning of the execution, without arguments. It can be used for initializing data structures. It will never need to be undone.TypeLetter(L)
— append to the end of the text a single lowercase letter chosen from .UndoCommands(U)
— undo the last commands, for a positive integer .GetLetter(P)
— return the letter at position in the current text, for a non-negative index . The first letter in the text has index . (This query is not a command and thus is ignored by the undo command.)
After the initial call to Init()
, the other routines can be called zero or more times in any order. It is guaranteed that
As for UndoCommands(U)
, it undoes the previous TypeLetter(L)
, then it removes UndoCommands(X)
for some value
Example
We show a possible sequence of calls, together with the state of the text after each call.
Call | Returns | Current text |
---|---|---|
Init() | ||
TypeLetter(a) | a | |
TypeLetter(b) | ab | |
GetLetter(1) | b | ab |
TypeLetter(d) | abd | |
UndoCommands(2) | a | |
UndoCommands(1) | abd | |
GetLetter(2) | d | abd |
TypeLetter(e) | abde | |
UndoCommands(1) | abd | |
UndoCommands(5) | ab | |
TypeLetter(c) | abc | |
GetLetter(2) | c | abc |
UndoCommands(2) | abd | |
GetLetter(2) | d | abd |
Subtask 1 [5 points]
- The total number of commands and queries is between
and (inclusive) and there will be no calls toUndoCommands
.
Subtask 2 [7 points]
- The total number of commands and queries is between
and (inclusive) and noUndoCommands
will be undone.
Subtask 3 [22 points]
- The total number of commands and queries is between
and (inclusive).
Subtask 4 [26 points]
- The total number of commands and queries is between
and (inclusive). All calls toGetLetter
will occur after all calls toTypeLetter
andUndoCommands
.
Subtask 5 [40 points]
- The total number of commands and queries is between
and (inclusive).
Implementation details
You must implement the subprograms described above using the following signatures.
C/C++ programs
void Init();
void TypeLetter(char L);
void UndoCommands(int U);
char GetLetter(int P);
Pascal programs
procedure Init;
procedure TypeLetter(L : Char);
procedure UndoCommands(U : LongInt);
function GetLetter(P : LongInt) : Char;
These subprograms must behave as described above. Of course you are free to implement other subprograms for their internal use. Your submissions must not interact in any way with standard input/output, nor with any other file.
Comments