用 s 条规则依次整理一个整数列表。 第一行给出 n,第二行给出 n 个整数,用空格分开。 第三行给出 s,接下来 s 行每行以 "名字 k" 的形式给出一条规则。 规则有六种,前三种改变列表中的每个数,后三种只保留满足条件的数。 add k:把每个数 x 变成 x + k。 mul k:把每个数 x 变成 x × k。 mod k:把每个数 x 变成 x 除以 k 的余数 r。 这里 r 大于等于 0 且小于 k,x - r 是 k 的倍数。 所以 -7 除以 3 的余数是 2。 gt k:只保留比 k 大的数。 lt k:只保留比 k 小的数。 div k:只保留 k 的倍数。 0 和负数也可能是 k 的倍数。 留下的数保持原来的顺序。 每用一条规则,就在一行里输出用到这条规则为止的列表,用单个空格分开。 列表为空时输出 -。 对空列表再用下一条规则,仍是空列表。 解答中要写两个函数,它们接收 "列表、规则函数、k" 并返回新列表。 一个改变每个数,另一个只保留满足条件的数。 对每条规则,把这条规则的函数作为值传入,调用这两个函数之一。
输入
1 ≤ n ≤ 300,1 ≤ s ≤ 20,开始的数在 -1,000,000 到 1,000,000 之间。 add 的 -1,000,000 ≤ k ≤ 1,000,000,mul 的 -10 ≤ k ≤ 10,mod 的 1 ≤ k ≤ 1,000,gt、lt 的 -1,000,000,000 ≤ k ≤ 1,000,000,000,div 的 1 ≤ k ≤ 100。 任何一步中,列表里每个数的绝对值都不超过 1,000,000,000
# 모든 수를 바꾸는 규칙(x, k → 새 수)def add(x, k): return x + kdef mul(x, k): return x * kdef mod(x, k): return x % k # Python의 %는 k가 양수면 늘 0 이상 k 미만# 남길지 정하는 규칙(x, k → 참·거짓)def gt(x, k): return x > kdef lt(x, k): return x < kdef div(x, k): return x % k == 0# 함수를 값으로 받는 함수 두 개def change_all(a, rule, k): return [rule(x, k) for x in a]def keep_only(a, rule, k): return [x for x in a if rule(x, k)]CHANGE = {"add": add, "mul": mul, "mod": mod}KEEP = {"gt": gt, "lt": lt, "div": div}n = int(input())a = list(map(int, input().split()))s = int(input())for _ in range(s): name, k = input().split() k = int(k) if name in CHANGE: a = change_all(a, CHANGE[name], k) else: a = keep_only(a, KEEP[name], k) print(" ".join(map(str, a)) if a else "-")
JavaScriptmain.js · 28 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");// 모든 수를 바꾸는 규칙(x, k → 새 수). JS의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다const CHANGE = { add: (x, k) => x + k, mul: (x, k) => x * k, mod: (x, k) => ((x % k) + k) % k,};// 남길지 정하는 규칙(x, k → 참·거짓)const KEEP = { gt: (x, k) => x > k, lt: (x, k) => x < k, div: (x, k) => x % k === 0,};// 함수를 값으로 받는 함수 두 개. map·filter는 새 배열을 돌려준다const changeAll = (a, rule, k) => a.map((x) => rule(x, k));const keepOnly = (a, rule, k) => a.filter((x) => rule(x, k));let a = lines[1].trim().split(/\s+/).map(Number);const s = Number(lines[2]);const out = [];for (let i = 0; i < s; i++) { const [name, ks] = lines[3 + i].trim().split(/\s+/); const k = Number(ks); a = name in CHANGE ? changeAll(a, CHANGE[name], k) : keepOnly(a, KEEP[name], k); // -0 % 3은 -0이지만 join은 "0"으로 쓴다 out.push(a.length ? a.join(" ") : "-");}console.log(out.join("\n"));
TypeScriptmain.ts · 30 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");type Change = (x: number, k: number) => number;type Keep = (x: number, k: number) => boolean;// 모든 수를 바꾸는 규칙. JS·TS의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다const CHANGE: Record<string, Change> = { add: (x, k) => x + k, mul: (x, k) => x * k, mod: (x, k) => ((x % k) + k) % k,};// 남길지 정하는 규칙const KEEP: Record<string, Keep> = { gt: (x, k) => x > k, lt: (x, k) => x < k, div: (x, k) => x % k === 0,};// 함수를 값으로 받는 함수 두 개const changeAll = (a: number[], rule: Change, k: number): number[] => a.map((x) => rule(x, k));const keepOnly = (a: number[], rule: Keep, k: number): number[] => a.filter((x) => rule(x, k));let a: number[] = lines[1].trim().split(/\s+/).map(Number);const s: number = Number(lines[2]);const out: string[] = [];for (let i = 0; i < s; i++) { const [name, ks] = lines[3 + i].trim().split(/\s+/); const k: number = Number(ks); a = name in CHANGE ? changeAll(a, CHANGE[name], k) : keepOnly(a, KEEP[name], k); out.push(a.length ? a.join(" ") : "-");}console.log(out.join("\n"));
JavaMain.java · 56 行
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.StringTokenizer;import java.util.function.BiPredicate;import java.util.function.IntBinaryOperator;public class Main { // 함수를 값으로 받는 함수 두 개 static List<Integer> changeAll(List<Integer> a, IntBinaryOperator rule, int k) { List<Integer> b = new ArrayList<>(); for (int x : a) b.add(rule.applyAsInt(x, k)); return b; } static List<Integer> keepOnly(List<Integer> a, BiPredicate<Integer, Integer> rule, int k) { List<Integer> b = new ArrayList<>(); for (int x : a) if (rule.test(x, k)) b.add(x); return b; } public static void main(String[] args) throws Exception { Map<String, IntBinaryOperator> change = new HashMap<>(); change.put("add", (x, k) -> x + k); change.put("mul", (x, k) -> x * k); change.put("mod", Math::floorMod); // %는 음수에서 음수가 나온다. floorMod는 0 이상 k 미만 Map<String, BiPredicate<Integer, Integer>> keep = new HashMap<>(); keep.put("gt", (x, k) -> x > k); keep.put("lt", (x, k) -> x < k); keep.put("div", (x, k) -> x % k == 0); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); in.readLine(); List<Integer> a = new ArrayList<>(); StringTokenizer st = new StringTokenizer(in.readLine()); while (st.hasMoreTokens()) a.add(Integer.parseInt(st.nextToken())); int s = Integer.parseInt(in.readLine().trim()); StringBuilder out = new StringBuilder(); for (int i = 0; i < s; i++) { st = new StringTokenizer(in.readLine()); String name = st.nextToken(); int k = Integer.parseInt(st.nextToken()); a = change.containsKey(name) ? changeAll(a, change.get(name), k) : keepOnly(a, keep.get(name), k); if (a.isEmpty()) { out.append("-\n"); continue; } for (int j = 0; j < a.size(); j++) out.append(j > 0 ? " " : "").append(a.get(j)); out.append('\n'); } System.out.print(out); }}
C#Main.cs · 50 行
using System;using System.Collections.Generic;using System.Text;class Program{ // 함수를 값으로 받는 함수 두 개 static List<int> ChangeAll(List<int> a, Func<int, int, int> rule, int k) { var b = new List<int>(); foreach (int x in a) b.Add(rule(x, k)); return b; } static List<int> KeepOnly(List<int> a, Func<int, int, bool> rule, int k) { var b = new List<int>(); foreach (int x in a) if (rule(x, k)) b.Add(x); return b; } static void Main() { var change = new Dictionary<string, Func<int, int, int>> { ["add"] = (x, k) => x + k, ["mul"] = (x, k) => x * k, ["mod"] = (x, k) => ((x % k) + k) % k, // %는 음수에서 음수가 나온다 }; var keep = new Dictionary<string, Func<int, int, bool>> { ["gt"] = (x, k) => x > k, ["lt"] = (x, k) => x < k, ["div"] = (x, k) => x % k == 0, }; Console.ReadLine(); var a = new List<int>(); foreach (string t in Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries)) a.Add(int.Parse(t)); int s = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); for (int i = 0; i < s; i++) { string[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int k = int.Parse(p[1]); a = change.TryGetValue(p[0], out var f) ? ChangeAll(a, f, k) : KeepOnly(a, keep[p[0]], k); sb.Append(a.Count > 0 ? string.Join(" ", a) : "-").Append('\n'); } Console.Write(sb); }}
C++main.cpp · 48 行
#include <functional>#include <iostream>#include <map>#include <string>#include <vector>using Change = std::function<int(int, int)>;using Keep = std::function<bool(int, int)>;// 함수를 값으로 받는 함수 두 개std::vector<int> changeAll(const std::vector<int> &a, const Change &rule, int k) { std::vector<int> b; for (int x : a) b.push_back(rule(x, k)); return b;}std::vector<int> keepOnly(const std::vector<int> &a, const Keep &rule, int k) { std::vector<int> b; for (int x : a) if (rule(x, k)) b.push_back(x); return b;}int main() { const std::map<std::string, Change> change = { {"add", [](int x, int k) { return x + k; }}, {"mul", [](int x, int k) { return x * k; }}, {"mod", [](int x, int k) { return (x % k + k) % k; }}, // %는 음수에서 음수가 나온다 }; const std::map<std::string, Keep> keep = { {"gt", [](int x, int k) { return x > k; }}, {"lt", [](int x, int k) { return x < k; }}, {"div", [](int x, int k) { return x % k == 0; }}, }; int n, s, k; std::cin >> n; std::vector<int> a(n); for (int &x : a) std::cin >> x; std::cin >> s; std::string name; for (int i = 0; i < s; i++) { std::cin >> name >> k; auto it = change.find(name); a = it != change.end() ? changeAll(a, it->second, k) : keepOnly(a, keep.at(name), k); if (a.empty()) std::cout << '-'; for (std::size_t j = 0; j < a.size(); j++) std::cout << (j ? " " : "") << a[j]; std::cout << '\n'; }}
Cmain.c · 46 行
#include <stdio.h>#include <string.h>/* 모든 수를 바꾸는 규칙과 남길지 정하는 규칙. 함수 포인터로 넘긴다 */int add(int x, int k) { return x + k; }int mul(int x, int k) { return x * k; }int mod(int x, int k) { return (x % k + k) % k; } /* C의 %는 음수에서 음수가 나온다 */int gt(int x, int k) { return x > k; }int lt(int x, int k) { return x < k; }int divisible(int x, int k) { return x % k == 0; }/* 함수를 값으로 받는 함수 두 개. 남긴 개수를 돌려준다 */int change_all(int *a, int n, int (*rule)(int, int), int k) { for (int i = 0; i < n; i++) a[i] = rule(a[i], k); return n;}int keep_only(int *a, int n, int (*rule)(int, int), int k) { int m = 0; for (int i = 0; i < n; i++) { if (rule(a[i], k)) a[m++] = a[i]; /* 앞으로 당겨 담는다 */ } return m;}int main(void) { struct { const char *name; int (*fn)(int, int); int changes; } rules[] = { {"add", add, 1}, {"mul", mul, 1}, {"mod", mod, 1}, {"gt", gt, 0}, {"lt", lt, 0}, {"div", divisible, 0}, }; int n, s, k, a[300]; char name[8]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &s); for (int step = 0; step < s; step++) { scanf("%7s %d", name, &k); for (int r = 0; r < 6; r++) { if (strcmp(rules[r].name, name) != 0) continue; n = rules[r].changes ? change_all(a, n, rules[r].fn, k) : keep_only(a, n, rules[r].fn, k); } if (n == 0) puts("-"); for (int i = 0; i < n; i++) printf(i + 1 < n ? "%d " : "%d\n", a[i]); } return 0;}
Craykonmain.cray · 90 行
// 모든 수를 바꾸는 규칙(x, k → 새 수)더하기(x, k){ 返回 x + k;}곱하기(x, k){ 返回 x * k;}나머지(x, k){ // 크레이콘의 %는 음수에서 음수가 나오니 k를 더해 한 번 더 나눈다 返回 (x % k + k) % k;}// 남길지 정하는 규칙(x, k → 참·거짓)큰것만(x, k){ 返回 x > k;}작은것만(x, k){ 返回 x < k;}배수만(x, k){ 返回 x % k == 0;}// 함수를 값으로 받는 함수 두 개. 크레이콘에는 람다가 없으니 이름으로 넘긴다모두바꾸기(a, 규칙, k){ b = []; 遍历 (x 在 a) { b.添加(규칙(x, k)); } 返回 b;}골라남기기(a, 규칙, k){ b = []; 遍历 (x 在 a) { 如果 (규칙(x, k)) { b.添加(x); } } 返回 b;}change = 字典();change["add"] = 더하기;change["mul"] = 곱하기;change["mod"] = 나머지;keep = 字典();keep["gt"] = 큰것만;keep["lt"] = 작은것만;keep["div"] = 배수만;控制台.读行();a = 控制台.读数字();s = 控制台.读行().转数字();循环 (i = 0; i < s; i++){ p = 控制台.读行().分割(); k = p[1].转数字(); 如果 (change.包含(p[0])) { a = 모두바꾸기(a, change[p[0]], k); } 否则 { a = 골라남기기(a, keep[p[0]], k); } 如果 (a.数量 == 0) { 控制台.输出("-"); } 否则 { 控制台.输出(a.连接(" ")); }}