{ }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 选择 里的 跳出(韩语 선택 里的 그만)也一样)。
所以要先用 if 判断 stop 再 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);