There is a list of n integers and a clipboard that is empty at first.
Process q commands in the given order.
copy l r copies the l-th through r-th items of the current list (both included) to the clipboard. The list does not change.
cut l r moves the l-th through r-th items of the current list (both included) to the clipboard and removes them from the list.
copy and cut erase what the clipboard held before and replace it with the new piece.
paste p inserts the clipboard's items, in the same order, right after the p-th number of the current list. If p is 0 they go at the very front.
The clipboard stays as it is after pasting. Pasting an empty clipboard does nothing.
A paste that would make the list longer than M items is ignored (one that makes it exactly M is done).
Positions count the first number as 1.
The first line gives n and M, the second line n integers, the third line q, and each of the next q lines one command. Values on a line are separated by single spaces.
After all commands, print the number of items in the list on the first line and the numbers of the list in order, separated by single spaces, on the second line.
If the list is empty, print - on the second line.
Input
1 ≤ n ≤ 1,000, n ≤ M ≤ 5,000, 1 ≤ q ≤ 500 (given as plain digits without commas). Numbers in the list are from -999 to 999. For copy and cut, with len the size of the list at that moment, 1 ≤ l ≤ r ≤ len (they are never given when the list is empty). For paste, 0 ≤ p ≤ len
Output
The size of the list on the first line; its numbers (separated by single spaces) or - on the second line
When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).
$ Ready
Open this on a computer to write and run code. On mobile you can read the problem and the solutions.
In other languagesShow solutions by language · 8 languages
Languages split into those that name a piece by 'start and end' and those that use 'start and count'. Start and end (end excluded): Python a[l-1:r], JS/TS a.slice(l - 1, r), Java a.subList(l - 1, r), C++ two iterators a.begin() + (l - 1), a.begin() + r. Start and count: C# a.GetRange(l - 1, r - l + 1), Craykon a.GetRange(l - 1, r - l + 1), C memcpy(clip, a + l - 1, count * sizeof(int)). Even inside JS, slice(start, end) and splice(start, count) differ. Removing: Python del a[l-1:r], JS/TS a.splice(l - 1, count) (it returns what it removed, so cut is one line), Java a.subList(l - 1, r).clear(), C# RemoveRange(start, count), C++ a.erase(first, last), C memmove. Inserting: Python a[p:p] = clip, JS/TS a.splice(p, 0, ...clip), Java a.addAll(p, clip), C# a.InsertRange(p, clip), C++ a.insert(pos, first, last), and in C memmove the tail away and memcpy. Craykon has nothing that removes or inserts several items at once, so build a new list: the front piece GetRange(0, p), then Add the clipboard and the back piece. Trap 1: swapping end and count, as in slice(l - 1, r - l + 1) or GetRange(l - 1, r). JS and Python quietly shorten an out-of-range piece, while C#, Java and Craykon stop with an error. Trap 2: copy or view? A Python slice, JS slice, C# GetRange and Craykon GetRange give a new list, but Java subList is a view into the original list. If you keep the view as the clipboard, using it again after inserting into or removing from the list throws ConcurrentModificationException. Make a copy with new ArrayList<>(a.subList(l - 1, r)). Trap 3: 'after the p-th' is index p counting from 0. With p - 1, when p = 0 Python gets a[-1:-1] and inserts before the last number. Trap 4: compare the limit with the size after pasting, current size + clipboard size, and exactly M is allowed (<=). Trap 5: cut also replaces the clipboard with the new piece. Trap 6: the r-th item belongs to the piece.
Pythonmain.py · 24 lines
import syslines = sys.stdin.read().split("\n")n, limit = map(int, lines[0].split())a = list(map(int, lines[1].split()))q = int(lines[2])clip = [] # 오려 두기 판for line in lines[3:3 + q]: p = line.split() if p[0] == "copy": l, r = int(p[1]), int(p[2]) clip = a[l - 1:r] # 조각은 새 목록(사본)이다 elif p[0] == "cut": l, r = int(p[1]), int(p[2]) clip = a[l - 1:r] del a[l - 1:r] else: at = int(p[1]) if len(a) + len(clip) <= limit: a[at:at] = clip # 빈 조각 자리에 넣으면 끼워 넣기가 된다print(len(a))print(" ".join(map(str, a)) if a else "-")
JavaScriptmain.js · 22 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const limit = Number(lines[0].trim().split(" ")[1]);const a = lines[1].trim().split(" ").map(Number);const q = Number(lines[2]);let clip = []; // 오려 두기 판for (const line of lines.slice(3, 3 + q)) { const p = line.trim().split(" "); if (p[0] === "copy") { const l = Number(p[1]), r = Number(p[2]); clip = a.slice(l - 1, r); // slice(시작, 끝): 끝은 들어가지 않는다. 사본을 준다 } else if (p[0] === "cut") { const l = Number(p[1]), r = Number(p[2]); clip = a.splice(l - 1, r - l + 1); // splice(시작, 개수): 뺀 것들을 돌려준다 } else { const at = Number(p[1]); if (a.length + clip.length <= limit) a.splice(at, 0, ...clip); }}console.log(a.length);console.log(a.length > 0 ? a.join(" ") : "-");
TypeScriptmain.ts · 24 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const limit = Number(lines[0].trim().split(" ")[1]);const a: number[] = lines[1].trim().split(" ").map(Number);const q = Number(lines[2]);let clip: number[] = []; // 오려 두기 판for (const line of lines.slice(3, 3 + q)) { const p = line.trim().split(" "); if (p[0] === "copy") { const l = Number(p[1]), r = Number(p[2]); clip = a.slice(l - 1, r); // slice(시작, 끝): 끝은 들어가지 않는다. 사본을 준다 } else if (p[0] === "cut") { const l = Number(p[1]), r = Number(p[2]); clip = a.splice(l - 1, r - l + 1); // splice(시작, 개수): 뺀 것들을 돌려준다 } else { const at = Number(p[1]); if (a.length + clip.length <= limit) a.splice(at, 0, ...clip); }}console.log(a.length);console.log(a.length > 0 ? a.join(" ") : "-");
JavaMain.java · 43 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;public class Main { public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int limit = Integer.parseInt(in.readLine().trim().split(" ")[1]); List<Integer> a = new ArrayList<>(); StringTokenizer st = new StringTokenizer(in.readLine()); while (st.hasMoreTokens()) a.add(Integer.parseInt(st.nextToken())); int q = Integer.parseInt(in.readLine().trim()); List<Integer> clip = new ArrayList<>(); // 오려 두기 판 for (int t = 0; t < q; t++) { String[] p = in.readLine().trim().split(" "); if (p[0].equals("copy")) { int l = Integer.parseInt(p[1]), r = Integer.parseInt(p[2]); // subList는 원래 목록을 들여다보는 창이라서, 새 목록에 담아 사본으로 만든다 clip = new ArrayList<>(a.subList(l - 1, r)); } else if (p[0].equals("cut")) { int l = Integer.parseInt(p[1]), r = Integer.parseInt(p[2]); clip = new ArrayList<>(a.subList(l - 1, r)); a.subList(l - 1, r).clear(); // 창을 비우면 원래 목록에서 빠진다 } else { int at = Integer.parseInt(p[1]); if (a.size() + clip.size() <= limit) a.addAll(at, clip); } } StringBuilder out = new StringBuilder(); out.append(a.size()).append('\n'); if (a.isEmpty()) out.append('-'); for (int i = 0; i < a.size(); i++) { if (i > 0) out.append(' '); out.append(a.get(i)); } System.out.println(out); }}
C#Main.cs · 38 lines
using System;using System.Collections.Generic;using System.Linq;class Program{ static void Main() { int limit = int.Parse(Console.ReadLine().Trim().Split(' ')[1]); List<int> a = Console.ReadLine().Trim().Split(' ').Select(int.Parse).ToList(); int q = int.Parse(Console.ReadLine().Trim()); var clip = new List<int>(); // 오려 두기 판 for (int t = 0; t < q; t++) { string[] p = Console.ReadLine().Trim().Split(' '); if (p[0] == "copy") { int l = int.Parse(p[1]), r = int.Parse(p[2]); clip = a.GetRange(l - 1, r - l + 1); // GetRange(시작, 개수): 사본을 준다 } else if (p[0] == "cut") { int l = int.Parse(p[1]), r = int.Parse(p[2]); clip = a.GetRange(l - 1, r - l + 1); a.RemoveRange(l - 1, r - l + 1); } else { int at = int.Parse(p[1]); if (a.Count + clip.Count <= limit) a.InsertRange(at, clip); } } Console.WriteLine(a.Count); Console.WriteLine(a.Count > 0 ? string.Join(" ", a) : "-"); }}
C++main.cpp · 34 lines
#include <iostream>#include <string>#include <vector>int main() { std::ios::sync_with_stdio(false); std::size_t n, limit; std::cin >> n >> limit; std::vector<int> a(n), clip; // clip: 오려 두기 판 for (int& x : a) std::cin >> x; int q; std::cin >> q; for (int t = 0; t < q; t++) { std::string cmd; std::cin >> cmd; if (cmd == "paste") { int at; std::cin >> at; if (a.size() + clip.size() <= limit) a.insert(a.begin() + at, clip.begin(), clip.end()); } else { int l, r; std::cin >> l >> r; // 반복자 두 개 [시작, 끝)로 조각을 가리킨다. assign은 사본을 만든다 clip.assign(a.begin() + (l - 1), a.begin() + r); if (cmd == "cut") a.erase(a.begin() + (l - 1), a.begin() + r); } } std::cout << a.size() << '\n'; if (a.empty()) std::cout << '-'; for (std::size_t i = 0; i < a.size(); i++) std::cout << (i ? " " : "") << a[i]; std::cout << '\n';}
Cmain.c · 43 lines
#include <stdio.h>#include <string.h>#define MAX 5000static int a[MAX], clip[MAX];int main(void) { int n, limit, q, clipLen = 0; scanf("%d %d", &n, &limit); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &q); for (int t = 0; t < q; t++) { char cmd[8]; scanf("%7s", cmd); if (strcmp(cmd, "paste") == 0) { int at; scanf("%d", &at); if (n + clipLen <= limit) { /* 뒤쪽을 조각 길이만큼 밀고(겹치므로 memmove) 빈 곳에 조각을 베낀다 */ memmove(a + at + clipLen, a + at, (size_t)(n - at) * sizeof(int)); memcpy(a + at, clip, (size_t)clipLen * sizeof(int)); n += clipLen; } } else { int l, r; scanf("%d %d", &l, &r); clipLen = r - l + 1; memcpy(clip, a + l - 1, (size_t)clipLen * sizeof(int)); /* 조각을 따로 베껴 둔다 */ if (strcmp(cmd, "cut") == 0) { memmove(a + l - 1, a + r, (size_t)(n - r) * sizeof(int)); n -= clipLen; } } } printf("%d\n", n); if (n == 0) printf("-"); for (int i = 0; i < n; i++) printf(i ? " %d" : "%d", a[i]); printf("\n"); return 0;}
Craykonmain.cray · 54 lines
첫줄 = Console.ReadNumbers();limit = 첫줄[1];a = Console.ReadNumbers();q = Console.ReadLine().ToNumber();clip = [];// 목록 뒤에 다른 목록의 것들을 차례로 붙인다붙이기(목록, 더할것){ foreach (x in 더할것) { 목록.Add(x); }}for (t = 0; t < q; t++){ p = Console.ReadLine().Trim().Split(" "); if (p[0] == "paste") { at = p[1].ToNumber(); if (a.Count + clip.Count <= limit) { // 앞 조각 + 오려 둔 것 + 뒤 조각 뒤 = a.GetRange(at, a.Count - at); a = a.GetRange(0, at); 붙이기(a, clip); 붙이기(a, 뒤); } } else { l = p[1].ToNumber(); r = p[2].ToNumber(); // 부분목록(시작, 개수)는 새 목록(사본)을 준다 clip = a.GetRange(l - 1, r - l + 1); if (p[0] == "cut") { 뒤 = a.GetRange(r, a.Count - r); a = a.GetRange(0, l - 1); 붙이기(a, 뒤); } }}Console.WriteLine(a.Count);if (a.Count > 0){ Console.WriteLine(a.Join(" "));}else{ Console.WriteLine("-");}