첫 줄에 노래 수 n이, 둘째 줄에 재생 목록의 노래 이름 n개가 차례대로 빈칸 하나씩으로 나뉘어 주어진다. 셋째 줄에 명령 수 q가, 다음 q줄에 명령이 하나씩 주어진다. 명령은 위에서부터 차례로 처리한다. move i j는 앞에서 i번째 노래를 빼낸 뒤, 그 노래가 앞에서 j번째가 되도록 다시 끼운다(자리는 1부터 센다). i와 j가 모두 1 이상이고, 이 명령을 하기 전의 노래 수 이하일 때만 할 수 있다(i와 j가 같으면 목록은 그대로다). remove s는 목록에서 맨 앞에 나오는 노래 s 하나를 뺀다. 목록에 s가 없으면 할 수 없다. reverse는 목록 전체의 차례를 거꾸로 뒤집는다. 목록이 비어 있어도 할 수 있다. 할 수 없는 명령은 건너뛰고, 건너뛴 명령의 수를 센다. stop이 나오면 그 뒤의 명령은 처리하지도 세지도 않고 끝낸다. 첫 줄에 마지막 재생 목록을 빈칸 하나씩으로 나눠 출력하고(비었으면 -), 둘째 줄에 건너뛴 명령의 수를 출력한다.
입력
1 ≤ n ≤ 2000, 1 ≤ q ≤ 2000. 노래 이름은 영어 소문자·숫자 1 ~ 10글자이고 같은 이름이 여러 번 나올 수 있다. move의 i, j는 −10 ~ 10,000의 정수
출력
두 줄: 마지막 재생 목록(비었으면 -), 건너뛴 명령의 수
예시 1 · stdin
5
intro rain sun moon outro
8
move 1 3
remove sun
remove star
reverse
move 4 1
move 0 2
stop
reverse
stdout
rain outro moon intro
2
예시 2 · stdin
2
x y
4
remove x
remove y
remove x
reverse
stdout
-
1
main.py
오류 목록00F8 ↓ · ⇧F8 ↑
입력(stdin)
실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).
$ 준비됐어요
코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.
다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이
명령마다 할 수 없으면 세고 건너뛰기(continue), stop이면 멈추기(break)예요. 첫 함정은 switch 안의 break: C·C++·Java·C#·JS·TS에서 switch 안의 break는 switch만 빠져나가고 반복은 계속 돌아요(크레이콘 선택 안의 그만도 같아요). 그래서 stop은 if로 먼저 묻고 break해요. 반대로 continue는 switch 안에서도 반복의 다음 바퀴로 가요. 둘째 함정은 뒤집기의 돌려주는 값이에요. Python songs.reverse()는 제자리에서 뒤집고 None을 돌려줘서 songs = songs.reverse()라고 쓰면 목록이 사라져요(새 목록이 필요하면 songs[::-1]). JS reverse()는 제자리에서 뒤집고 같은 배열을 돌려줘요. Java Collections.reverse(songs), C# List<T>.Reverse(), C++ std::reverse(begin, end), 크레이콘 songs.뒤집기()도 제자리에서 뒤집고, C는 양 끝에서 바꿔 가요. 셋째 함정은 move의 차례: 먼저 빼고(pop(i - 1), splice(i - 1, 1), Java remove(int), C# RemoveAt, 크레이콘 자리빼기) 그다음 끼워야(insert, splice(j - 1, 0, x), add(j - 1, x), Insert, 끼우기) j가 "뺀 뒤의 자리"가 돼요. 넷째 함정은 범위 검사: Python은 pop(-1)이 맨 뒤를 빼서 i = 0이 오류 없이 엉뚱한 노래를 옮기니 1 이상인지도 꼭 물어요. Java remove는 remove(int)(자리)와 remove(Object)(값)가 따로 있어요.
Pythonmain.py · 25 줄
input()songs = input().split()q = int(input())skipped = 0for _ in range(q): cmd, *arg = input().split() if cmd == "stop": break # 남은 명령은 읽지도 세지도 않는다 if cmd == "reverse": songs.reverse() # 제자리에서 뒤집는다(돌려주는 값은 None) elif cmd == "remove": if arg[0] not in songs: skipped += 1 continue songs.remove(arg[0]) # 맨 앞의 것 하나 else: i, j = int(arg[0]), int(arg[1]) # 0이나 음수를 그대로 쓰면 Python은 뒤에서부터 세어 버린다 if not (1 <= i <= len(songs) and 1 <= j <= len(songs)): skipped += 1 continue song = songs.pop(i - 1) songs.insert(j - 1, song) # 뺀 뒤의 목록에서 j번째 자리print(" ".join(songs) if songs else "-")print(skipped)
JavaScriptmain.js · 28 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");const songs = lines[1].trim().split(" ");const q = Number(lines[2]);let skipped = 0;for (const line of lines.slice(3, 3 + q)) { const [cmd, a, b] = line.trim().split(" "); if (cmd === "stop") break; // 남은 명령은 세지 않는다 if (cmd === "reverse") { songs.reverse(); // 제자리에서 뒤집는다 } else if (cmd === "remove") { const at = songs.indexOf(a); if (at === -1) { skipped++; continue; } songs.splice(at, 1); } else { const i = Number(a), j = Number(b); if (!(1 <= i && i <= songs.length && 1 <= j && j <= songs.length)) { skipped++; continue; } const [song] = songs.splice(i - 1, 1); // 먼저 빼고 songs.splice(j - 1, 0, song); // 뺀 뒤의 목록에서 j번째 자리에 끼운다 }}console.log(songs.length > 0 ? songs.join(" ") : "-");console.log(skipped);
TypeScriptmain.ts · 29 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const songs: string[] = lines[1].trim().split(" ");const q = Number(lines[2]);let skipped = 0;for (const line of lines.slice(3, 3 + q)) { const [cmd, a, b] = line.trim().split(" "); if (cmd === "stop") break; // 남은 명령은 세지 않는다 if (cmd === "reverse") { songs.reverse(); // 제자리에서 뒤집는다 } else if (cmd === "remove") { const at = songs.indexOf(a); if (at === -1) { skipped++; continue; } songs.splice(at, 1); } else { const i = Number(a), j = Number(b); if (!(1 <= i && i <= songs.length && 1 <= j && j <= songs.length)) { skipped++; continue; } const [song] = songs.splice(i - 1, 1); // 먼저 빼고 songs.splice(j - 1, 0, song); // 뺀 뒤의 목록에서 j번째 자리에 끼운다 }}console.log(songs.length > 0 ? songs.join(" ") : "-");console.log(skipped);
JavaMain.java · 34 줄
import java.io.*;import java.util.*;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); br.readLine(); List<String> songs = new ArrayList<>(Arrays.asList(br.readLine().trim().split(" "))); int q = Integer.parseInt(br.readLine().trim()); int skipped = 0; for (int t = 0; t < q; t++) { String[] p = br.readLine().trim().split(" "); if (p[0].equals("stop")) break; // switch 안의 break는 switch만 빠져나가서 if로 쓴다 if (p[0].equals("reverse")) { Collections.reverse(songs); } else if (p[0].equals("remove")) { if (!songs.remove(p[1])) { // remove(Object): 맨 앞의 것 하나, 없으면 false skipped++; continue; } } else { int i = Integer.parseInt(p[1]), j = Integer.parseInt(p[2]); if (i < 1 || i > songs.size() || j < 1 || j > songs.size()) { skipped++; continue; } String song = songs.remove(i - 1); // remove(int): 그 자리의 것 songs.add(j - 1, song); } } System.out.println(songs.isEmpty() ? "-" : String.join(" ", songs)); System.out.println(skipped); }}
C#Main.cs · 44 줄
using System;using System.Collections.Generic;class Program{ static void Main() { Console.ReadLine(); var songs = new List<string>(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries)); int q = int.Parse(Console.ReadLine().Trim()); int skipped = 0; for (int t = 0; t < q; t++) { string[] p = Console.ReadLine().Trim().Split(' '); if (p[0] == "stop") break; // switch 안의 break는 switch만 빠져나가서 if로 쓴다 if (p[0] == "reverse") { songs.Reverse(); // List<T>.Reverse()는 제자리에서 뒤집는다 } else if (p[0] == "remove") { if (!songs.Remove(p[1])) { skipped++; continue; } } else { int i = int.Parse(p[1]), j = int.Parse(p[2]); if (i < 1 || i > songs.Count || j < 1 || j > songs.Count) { skipped++; continue; } string song = songs[i - 1]; songs.RemoveAt(i - 1); songs.Insert(j - 1, song); } } Console.WriteLine(songs.Count > 0 ? string.Join(" ", songs) : "-"); Console.WriteLine(skipped); }}
C++main.cpp · 44 줄
#include <algorithm>#include <iostream>#include <sstream>#include <string>#include <vector>int main() { int n, q; std::cin >> n; std::vector<std::string> songs(n); for (auto& s : songs) std::cin >> s; std::cin >> q; int skipped = 0; for (int t = 0; t < q; t++) { std::string cmd; std::cin >> cmd; if (cmd == "stop") break; // 남은 명령은 세지 않는다 if (cmd == "reverse") { std::reverse(songs.begin(), songs.end()); } else if (cmd == "remove") { std::string w; std::cin >> w; auto it = std::find(songs.begin(), songs.end(), w); if (it == songs.end()) { skipped++; continue; } songs.erase(it); } else { int i, j, len = songs.size(); std::cin >> i >> j; if (i < 1 || i > len || j < 1 || j > len) { skipped++; continue; } std::string song = songs[i - 1]; songs.erase(songs.begin() + (i - 1)); songs.insert(songs.begin() + (j - 1), song); } } if (songs.empty()) std::cout << "-"; for (size_t k = 0; k < songs.size(); k++) std::cout << (k ? " " : "") << songs[k]; std::cout << "\n" << skipped << "\n";}
Cmain.c · 64 줄
#include <stdio.h>#include <string.h>static char songs[2000][11];static int len;/* 자리 at의 노래를 빼고 뒤를 한 칸씩 당긴다 */static void remove_at(int at) { memmove(songs[at], songs[at + 1], sizeof(songs[0]) * (len - at - 1)); len--;}/* 자리 at에 끼우고 뒤를 한 칸씩 민다 */static void insert_at(int at, const char *s) { memmove(songs[at + 1], songs[at], sizeof(songs[0]) * (len - at)); strcpy(songs[at], s); len++;}int main(void) { int q, skipped = 0; scanf("%d", &len); for (int i = 0; i < len; i++) scanf("%10s", songs[i]); scanf("%d", &q); for (int t = 0; t < q; t++) { char cmd[8], w[11]; scanf("%7s", cmd); /* switch 안의 break는 switch만 빠져나가니 멈추기는 if로 쓴다 */ if (strcmp(cmd, "stop") == 0) break; if (strcmp(cmd, "reverse") == 0) { for (int a = 0, b = len - 1; a < b; a++, b--) { char tmp[11]; strcpy(tmp, songs[a]); strcpy(songs[a], songs[b]); strcpy(songs[b], tmp); } } else if (strcmp(cmd, "remove") == 0) { scanf("%10s", w); int at = -1; for (int k = 0; k < len; k++) if (strcmp(songs[k], w) == 0) { at = k; break; } if (at < 0) { skipped++; continue; } remove_at(at); } else { int i, j; scanf("%d %d", &i, &j); if (i < 1 || i > len || j < 1 || j > len) { skipped++; continue; } char song[11]; strcpy(song, songs[i - 1]); remove_at(i - 1); insert_at(j - 1, song); } } if (len == 0) printf("-"); for (int k = 0; k < len; k++) printf(k ? " %s" : "%s", songs[k]); printf("\n%d\n", skipped); return 0;}
Craykonmain.cray · 48 줄
콘솔.줄읽기();songs = 콘솔.줄읽기().공백제거().나누기();q = 콘솔.줄읽기().수로변환();skipped = 0;반복 (t = 0; t < q; t++){ p = 콘솔.줄읽기().공백제거().나누기(); cmd = p[0]; // 선택 안의 그만은 선택만 빠져나가니 멈추기는 만약으로 쓴다 만약 (cmd == "stop") { 그만; } 만약 (cmd == "reverse") { songs.뒤집기(); } 아니면 만약 (cmd == "remove") { 만약 (!songs.빼기(p[1])) { skipped++; 건너뛰기; } } 아니면 { i = p[1].수로변환(); j = p[2].수로변환(); 만약 (i < 1 || i > songs.개수 || j < 1 || j > songs.개수) { skipped++; 건너뛰기; } song = songs[i - 1]; songs.자리빼기(i - 1); songs.끼우기(j - 1, song); }}만약 (songs.개수 > 0){ 콘솔.쓰기(songs.잇기(" "));}아니면{ 콘솔.쓰기("-");}콘솔.쓰기(skipped);