このページについて
このページは、paiza ラーニング内に開設されているコンテンツ「レベルアップ問題集」で取り扱われているプログラミング課題について、独自の見解を述べたものです。
見解については、paizaラーニングの規約に基づき、許可されている範囲でのみ公開していますが、その内容については paiza とは一切関係なく、また paiza の立場を反映したものではありませんのでご注意ください。
挑戦する課題
レベルアップ問題集のCランクレベルアップメニューから「辞書 (paizaランク C 相当)」を取り上げます。
以下は、問題公開 Web ページからの引用です。
問題
p 人のグループ A , q 人のグループ B , r 人のグループ C があります。各グループのメンバーにはそれぞれ番号がつけられており、 A グループの i 番目の人は B グループの j 番目の人に仕事を任せ、 B グループの j 番目の人は与えられた仕事を C グループの k 番目の人に任せます。すると結局、 A グループの i 番目の人の仕事をするのは C グループの k 番目の人だということになります。
パイザ君は A グループの各人の仕事を結局 C グループの誰が行うことになるのか知りたがっています。 A グループの人のそれぞれが最終的に C グループの誰に仕事を頼むことになるのかを、 A グループの人の番号が小さい順に p 行出力してください。
入力される値
入力は以下のフォーマットで与えられます。
1 2 3 4 5 6 7 |
p q r i_1 j_1 ... i_p j_p j'_1 k_1 ... j'_q k_q |
- 1 行目には A グループ、 B グループ、 C グループのそれぞれの人数 p , q , r が半角スペース区切りで与えられます。
- 2 行目から (p + 1) 行目までは A グループの人の番号とその人が仕事を頼む B グループの人の番号 i_a, j_a (1 ≤ a ≤ p) が半角スペース区切りで、 (p + 2) 行目から (p + q + 2) 行目までは B グループの人の番号とその人が仕事を頼む C グループの人の番号 j’_b , k_b (1 ≤ b ≤ q) が半角スペース区切りで与えられます。
期待する出力
A グループの
i_c 番目の人が C グループの
k_c 番目の人に仕事を頼むとしたとき (1 ≤
c ≤
p) 、各
i_c, k_c をそれぞれ半角スペース区切りで、
i_c が小さい順に
p 行出力してください。
末尾に改行を入れ、余計な文字、空行を含んではいけません。
考え方
執筆中。
辞書をソートする場合には、 sorted(by:) を使い、 key と value のどちらでソートするか指定するが、結果はタプル列で返される点に注意。
解答例
辞書をソート使う場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// p, q, r let ia = readLine()!.split(separator: " ").map { Int($0)! } // A の人数 let p = ia[0] // B の人数 let q = ia[1] // C の人数(使わない) let r = ia[2] func readJobs(_ i: Int) -> [Int: Int] { var jobs:[Int: Int] = [:] for _ in 0..<i { // 仕事の割り当てを読み込む let ia = readLine()!.split(separator: " ").map { Int($0)! } jobs[ia[0]] = ia[1] } return jobs } // A -> B の割り当て var a2b = readJobs(p) // B -> C の割り当て var b2c = readJobs(q) for i in a2b { // A が頼む B の番号 let b = a2b[i.key]! // B が頼む C の番号 let c = b2c[b]! // A が頼む B の番号を C と入れ替える a2b[i.key] = c } // A -> B (実際は A -> C) の割り当てを、Aの番号が若い順に並び替え、仕事を依頼する C の番号を添えて出力 a2b.sorted(by: { $0.key < $1.key}).forEach{ print($0.key, $0.value) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
// p, q, r let ia = readLine()!.split(separator: " ").map { Int($0)! } // A の人数 let p = ia[0] // B の人数 let q = ia[1] // C の人数(使わない) let r = ia[2] func readJobs(_ i: Int) -> [(Int, Int)] { var jobs:[(Int, Int)] = [] for _ in 0..<i { // 仕事の割り当てを読み込む let ia = readLine()!.split(separator: " ").map { Int($0)! } jobs.append((ia[0], ia[1])) } return jobs } // A -> B の割り当て var a2b = readJobs(p) // B -> C の割り当て var b2c = readJobs(q) for i in 0..<a2b.count { // A が頼む B の番号 let b = a2b[i].1 // B が頼む C の番号 let indexC = b2c.firstIndex(where: {$0.0 == b})! let c = b2c[indexC].1 // A が頼む B の番号を C と入れ替える a2b[i].1 = c } // A -> B (実際は A -> C) の割り当てを、Aの番号が若い順に並び替え、仕事を依頼する C の番号を添えて出力 a2b.sorted(by: {$0.0 < $1.0}).forEach{ print($0.0, $0.1) } |