{ }codelper
リストからの削除リストの反転break・continueP0110

再生リストを直す

一行目に曲の数 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
入力(stdin)

実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。

$ 準備完了

コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。

ほかの言語では?言語別の解答を見る · 8 言語の解答

命令ごとに、できなければ数えて飛ばし(continue)、stop なら止めます(break)。
一つ目の落とし穴は switch の中の break:C・C++・Java・C#・JS・TS では switch の中の break は switch だけを抜け、ループは回り続けます(Craykon の 選択 の中の 抜ける(韓国語 선택 の中の 그만)も同じです)。
だから 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)、Craykon songs.逆に()(韓国語 songs.뒤집기())、C は両端から入れ替えていきます。
三つ目は move の順番:先に取り出して(pop(i - 1)、splice(i - 1, 1)、Java remove(int)、C# RemoveAt、Craykon 位置で取り除く(韓国語 자리빼기))から入れる(insert、splice(j - 1, 0, x)、add(j - 1, x)、Insert、Craykon 挿入(韓国語 끼우기))と、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);