A stationery shop has n notebooks and m pens, each with a price. Notebooks and pens are numbered from 1 in the order given.
Today only notebooks priced at T or more get d taken off. A notebook cheaper than T keeps its price.
One notebook and one pen together make a gift set. The price of a set is the notebook's price after the discount plus the pen's price.
Print the following three things in order.
First, print the n notebook prices after the discount on one line, in the order given.
Second, print on one line the number of sets whose price is at most B, and then print each such set on its own line as notebook number, pen number and set price. Print the sets in increasing order of notebook number, and for the same notebook in increasing order of pen number.
Third, print on one line the prices of the sets that cost at most B, each distinct price once, from smallest to largest. If there is no such set, print -.
When a line has several numbers, separate them with one space.
This problem is practice for short expressions that build a new list from a list (comprehensions in Python, map/filter and the like elsewhere), but grading only looks at the output, so plain loops are fine too.
Input
The first line has n, m, B, T and d separated by one space. The second line has the n notebook prices and the third line has the m pen prices, separated by one space. 1 ≤ n, m ≤ 60, every price is from 1 to 100,000, 1 ≤ B ≤ 200,000, 1 ≤ d < T ≤ 100,000. All numbers are integers
Output
The first line has the n notebook prices after the discount, the second line the number of sets costing at most B, then one line per set with notebook number, pen number and set price, and the last line the distinct set prices (or - if none). Print numbers as plain digits without commas
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
A Python comprehension builds a new list from a list in one line. This problem is three of them: [p - d if p >= T else p for p in notes] to change values, [... for i ... for j ... if ...] to loop two deep and filter, and the set comprehension {t for ...} to keep each value once. Other languages do the same job with other tools. JS/TS use map, flatMap, filter and new Set; Java uses streams with map, flatMap, filter, distinct and sorted; C# uses LINQ's Select, from … from … where … select, Distinct and OrderBy. C++ uses transform only for changing values, then two for loops that collect into a std::set. C and Craykon have no such expression, so a loop adds items one by one to an empty array or list (Craykon Add), sorts (C qsort, Craykon Sort) and skips a value equal to the one just before it. Trap one: in a Python comprehension the place of if changes its meaning. a if cond else b before for chooses a value, so every item stays; if after for is a filter, so items drop out. Writing [p - d for p in notes if p >= T] in the example loses the 600 notebook and the first line becomes 1000 800. Trap two: with two fors the left one is the outer loop. Swap them and the pens become the outer loop, so in the example 3 1 1100 comes out before 2 2 1100. Two froms in C# LINQ follow the same order. Trap three: braces {...} make a set and brackets [...] make a list. With brackets equal values stay, and the last line of the example becomes 900 1100 1100 1300 1300. Trap four: JS/TS sort() without a compare function turns numbers into strings and compares them in dictionary order. The last line of the example becomes 1100 1300 900, so write sort((x, y) => x - y). Python's sorted, Java's sorted, C#'s OrderBy and Craykon's Sort compare numbers by size.
Pythonmain.py · 21 lines
import syslines = sys.stdin.read().split("\n")n, m, B, T, d = map(int, lines[0].split())notes = list(map(int, lines[1].split()))pens = list(map(int, lines[2].split()))# 조건식은 for 앞에: 모든 공책이 남고 값만 바뀐다sale = [p - d if p >= T else p for p in notes]# for 두 개는 적힌 차례대로 바깥 → 안쪽, 뒤의 if는 거르는 조건pairs = [(i, j, a + b) for i, a in enumerate(sale, 1) for j, b in enumerate(pens, 1) if a + b <= B]# 집합 내포로 같은 값을 하나로 모은다totals = sorted({t for _, _, t in pairs})out = [" ".join(map(str, sale)), str(len(pairs))]out += [f"{i} {j} {t}" for i, j, t in pairs]out.append(" ".join(map(str, totals)) if totals else "-")print("\n".join(out))
JavaScriptmain.js · 18 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, m, B, T, d] = lines[0].trim().split(" ").map(Number);const notes = lines[1].trim().split(" ").map(Number);const pens = lines[2].trim().split(" ").map(Number);// map: 모든 공책이 남고 값만 바뀐다const sale = notes.map((p) => (p >= T ? p - d : p));// flatMap으로 두 겹을 한 줄로 펴고, filter로 거른다const pairs = sale .flatMap((a, i) => pens.map((b, j) => [i + 1, j + 1, a + b])) .filter(([, , t]) => t <= B);// Set으로 같은 값을 하나로 모으고, 수로 견주어 정렬한다const totals = [...new Set(pairs.map(([, , t]) => t))].sort((x, y) => x - y);const out = [sale.join(" "), String(pairs.length)];for (const [i, j, t] of pairs) out.push(`${i} ${j} ${t}`);out.push(totals.length > 0 ? totals.join(" ") : "-");console.log(out.join("\n"));
TypeScriptmain.ts · 22 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [, , B, T, d]: number[] = lines[0].trim().split(" ").map(Number);const notes: number[] = lines[1].trim().split(" ").map(Number);const pens: number[] = lines[2].trim().split(" ").map(Number);type Pair = [number, number, number];// map: 모든 공책이 남고 값만 바뀐다const sale: number[] = notes.map((p) => (p >= T ? p - d : p));// flatMap으로 두 겹을 한 줄로 펴고, filter로 거른다const pairs: Pair[] = sale .flatMap((a, i) => pens.map((b, j): Pair => [i + 1, j + 1, a + b])) .filter(([, , t]) => t <= B);// Set으로 같은 값을 하나로 모으고, 수로 견주어 정렬한다const totals: number[] = [...new Set(pairs.map(([, , t]) => t))].sort((x, y) => x - y);const out: string[] = [sale.join(" "), String(pairs.length)];for (const [i, j, t] of pairs) out.push(`${i} ${j} ${t}`);out.push(totals.length > 0 ? totals.join(" ") : "-");console.log(out.join("\n"));
JavaMain.java · 41 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Arrays;import java.util.stream.Collectors;import java.util.stream.IntStream;public class Main { static int[] readInts(BufferedReader in) throws IOException { return Arrays.stream(in.readLine().trim().split(" ")).mapToInt(Integer::parseInt).toArray(); } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); int[] head = readInts(in); int n = head[0], m = head[1], B = head[2], T = head[3], d = head[4]; int[] notes = readInts(in); int[] pens = readInts(in); // 스트림의 map: 모든 공책이 남고 값만 바뀐다 int[] sale = Arrays.stream(notes).map(p -> p >= T ? p - d : p).toArray(); // 두 겹은 flatMap으로 펴고 filter로 거른다 int[][] pairs = IntStream.range(0, n).boxed() .flatMap(i -> IntStream.range(0, m).mapToObj(j -> new int[] {i + 1, j + 1, sale[i] + pens[j]})) .filter(p -> p[2] <= B) .toArray(int[][]::new); // distinct로 같은 값을 하나로 모으고 sorted로 정렬한다 int[] totals = Arrays.stream(pairs).mapToInt(p -> p[2]).distinct().sorted().toArray(); StringBuilder out = new StringBuilder(); out.append(Arrays.stream(sale).mapToObj(String::valueOf).collect(Collectors.joining(" "))).append('\n'); out.append(pairs.length).append('\n'); for (int[] p : pairs) { out.append(p[0]).append(' ').append(p[1]).append(' ').append(p[2]).append('\n'); } out.append(totals.length > 0 ? Arrays.stream(totals).mapToObj(String::valueOf).collect(Collectors.joining(" ")) : "-"); System.out.println(out); }}
C#Main.cs · 34 lines
using System;using System.Linq;using System.Text;class Program{ static int[] ReadInts() => Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); static void Main() { int[] head = ReadInts(); int n = head[0], m = head[1], B = head[2], T = head[3], d = head[4]; int[] notes = ReadInts(); int[] pens = ReadInts(); // LINQ Select: 모든 공책이 남고 값만 바뀐다 int[] sale = notes.Select(p => p >= T ? p - d : p).ToArray(); // from 두 개는 적힌 차례대로 바깥 → 안쪽, where는 거르는 조건 var pairs = (from i in Enumerable.Range(0, n) from j in Enumerable.Range(0, m) where sale[i] + pens[j] <= B select (I: i + 1, J: j + 1, Total: sale[i] + pens[j])).ToList(); // Distinct로 같은 값을 하나로 모으고 OrderBy로 정렬한다 int[] totals = pairs.Select(p => p.Total).Distinct().OrderBy(t => t).ToArray(); var sb = new StringBuilder(); sb.Append(string.Join(" ", sale)).Append('\n'); sb.Append(pairs.Count).Append('\n'); foreach (var p in pairs) sb.Append($"{p.I} {p.J} {p.Total}\n"); sb.Append(totals.Length > 0 ? string.Join(" ", totals) : "-").Append('\n'); Console.Write(sb); }}
C++main.cpp · 48 lines
#include <algorithm>#include <array>#include <iostream>#include <set>#include <vector>using namespace std;int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m, B, T, d; cin >> n >> m >> B >> T >> d; vector<int> notes(n), pens(m); for (int &p : notes) cin >> p; for (int &p : pens) cin >> p; // transform: 모든 공책이 남고 값만 바뀐다 vector<int> sale(n); transform(notes.begin(), notes.end(), sale.begin(), [&](int p) { return p >= T ? p - d : p; }); // 두 겹은 for문 두 개로 쓴다 vector<array<int, 3>> pairs; set<int> totals; // 같은 값은 하나만, 늘 정렬된 채로 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { int t = sale[i] + pens[j]; if (t <= B) { pairs.push_back({i + 1, j + 1, t}); totals.insert(t); } } } for (int i = 0; i < n; i++) cout << (i ? " " : "") << sale[i]; cout << '\n' << pairs.size() << '\n'; for (const auto &p : pairs) cout << p[0] << ' ' << p[1] << ' ' << p[2] << '\n'; if (totals.empty()) { cout << "-\n"; } else { bool first = true; for (int t : totals) { cout << (first ? "" : " ") << t; first = false; } cout << '\n'; } return 0;}
Cmain.c · 52 lines
#include <stdio.h>#include <stdlib.h>#define MAXN 60static int cmp_int(const void *a, const void *b) { int x = *(const int *)a, y = *(const int *)b; return (x > y) - (x < y);}int main(void) { int n, m, B, T, d; static int sale[MAXN], pens[MAXN]; static int pi[MAXN * MAXN], pj[MAXN * MAXN], pt[MAXN * MAXN], totals[MAXN * MAXN]; scanf("%d %d %d %d %d", &n, &m, &B, &T, &d); /* C에는 내포가 없다. 읽으면서 바로 값을 바꾼다 */ for (int i = 0; i < n; i++) { int p; scanf("%d", &p); sale[i] = p >= T ? p - d : p; } for (int j = 0; j < m; j++) scanf("%d", &pens[j]); int count = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (sale[i] + pens[j] <= B) { pi[count] = i + 1; pj[count] = j + 1; pt[count] = sale[i] + pens[j]; totals[count] = pt[count]; count++; } } } for (int i = 0; i < n; i++) printf(i ? " %d" : "%d", sale[i]); printf("\n%d\n", count); for (int k = 0; k < count; k++) printf("%d %d %d\n", pi[k], pj[k], pt[k]); if (count == 0) { printf("-\n"); return 0; } /* 정렬한 뒤, 바로 앞과 같은 값은 건너뛴다 */ qsort(totals, (size_t)count, sizeof(int), cmp_int); for (int k = 0; k < count; k++) { if (k > 0 && totals[k] == totals[k - 1]) continue; printf(k ? " %d" : "%d", totals[k]); } printf("\n"); return 0;}
Craykonmain.cray · 62 lines
첫줄 = Console.ReadNumbers();n = 첫줄[0];m = 첫줄[1];B = 첫줄[2];T = 첫줄[3];d = 첫줄[4];notes = Console.ReadNumbers();pens = Console.ReadNumbers();// 크레이콘에는 내포가 없다. 빈 목록에 하나씩 넣는다sale = [];foreach (p in notes){ if (p >= T) { sale.Add(p - d); } else { sale.Add(p); }}Console.WriteLine(sale);줄들 = [];totals = [];for (i = 0; i < n; i++){ for (j = 0; j < m; j++) { t = sale[i] + pens[j]; if (t <= B) { 줄들.Add(i + 1 + " " + (j + 1) + " " + t); totals.Add(t); } }}Console.WriteLine(줄들.Count);foreach (줄 in 줄들){ Console.WriteLine(줄);}if (totals.Count == 0){ Console.WriteLine("-");}else{ // 정렬한 뒤, 바로 앞과 같은 값은 건너뛴다 totals.Sort(); 고른것 = [totals[0]]; for (k = 1; k < totals.Count; k++) { if (totals[k] != totals[k - 1]) { 고른것.Add(totals[k]); } } Console.WriteLine(고른것);}