【競プロ/Swift】まよコン 2023/03/17

# 注意事項
本記事は復習のための日記的なものであり、丁寧な解説を求めている方には不十分かと思われますので、ご了承のほどお願いいたします。

# 正解済み問題
## B - A Reverse
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc233/tasks/abc233_b)

**解答**
入力値の決められた区間を反転さして出力。

```swift
import Foundation
let lr = readLine()!.split(separator: " ").map{Int($0)! - 1}
let s = Array(readLine()!)

var front = ""
var center = ""
var back = ""

for index in 0..<s.count {
    if index >= lr[0] && index <= lr[1] {
        center += String(s[index])
    } else if index < lr[0] {
        front += String(s[index])
    } else {
        back += String(s[index])
    }
}
center = String(center.reversed())
print(front + center + back)
```
# 誤答及び、未解答問題
## C - Ameba
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc274/tasks/abc274_c)

**正答**
解き方というか、問題の意味がわからなくて諦めた。
解説や他の人の解答を見て、ギリ分かったような分からないようなふわふわした感じなので、とりあえず正解の解答だけ残しておく。

```swift
func ABC274C() {
    func readInt() -> Int {
        return Int(readLine()!)!
    }
    
    func readIntItems() -> [Int] {
        let strings = readLine()!.split(separator: " ")
        return strings.map { Int($0)! }
    }
    let N = readInt()
    let A = readIntItems()

    // 何世代前からの配列を作る。（これが最終的に出力する答え）
    var countArray = [Int](repeating: 0, count: 2*N+1)
    for i in 0..<N {
        //アメーバの数をcountArrayのindexとして使いたいため、-1している。（アメーバの最小値は１のため）
        let a = A[i]-1
        countArray[(i+1)*2-1] += countArray[a] + 1
        countArray[(i+1)*2] += countArray[a] + 1
    }
    for a in countArray {
        print(a)
    }

}
ABC274C()
```

## C - Martial artist
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc226/tasks/abc226_c)

**誤答１**
N個目の技を習得するために必要な技のコストだけ計算しており、WAで終了。

```swift
let n = Int(readLine()!)!
var skills: [[Int]] = []

for _ in 0..<n {
    let tka = readLine()!.split(separator: " ").map{Int($0)!}
    skills.append(tka)
}

let nK = skills[n-1][1]

var needSlills: [Int] = Array(skills[n-1][2...(1 + nK)])
var score: Int64 = Int64(skills[n-1][0])
for index in needSlills {
    score += Int64(skills[index-1][0])
}
print(score)
```

**誤答２**
N個目の技を覚えるために求められる技を覚えるために求められる技を計算しようと、重複しないSet配列でループを回したが、何かが間違っていたのかWAで終了。
せめてTLEになって欲しかった。。

```swift
let n = Int(readLine()!)!
var skills: [[Int]] = []

for _ in 0..<n {
    let tka = readLine()!.split(separator: " ").map{Int($0)!}
    skills.append(tka)
}

let nK = skills[n-1][1]

var needSlills: Set<Int> = Set(skills[n-1][2...(1 + nK)])
for index in needSlills {
    let k = skills[index][1]
    for num in skills[index][2...(1+k)] {
        needSlills.insert(num)
    }
}


var score: Int64 = Int64(skills[n-1][0])
for index in needSlills {
    score += Int64(skills[index-1][0])
}
print(score)
```

**正答**
答えは案外理解しやすいコードでかける。
集計しないといけない技のマーキングリストを作って、それに対して集計したいindexの値をtrueに変えていく。
集計の肝なのは１周目にN個目の技の必要技indexから回している点、あとは１周目でマークした値を順に見ていき、必要であれば必要技indexをtrueにしていけば漏れなく集計できる。
最後にマーキングしたindexの習得時間を集計すれば、正解できる。


```swift
let N = Int(readLine()!)!
var waza: [[Int]] = .init(repeating: [], count: N+1)
let TKA = (0..<N).map{_ in readLine()!.split(separator:" ").map{Int(String($0))!}}

var marks: [Bool] = .init(repeating: false, count: N+1)
marks[N] = true

for ii in 0..<N {
    let i = N-ii
    if !marks[i] { continue }
    for req in TKA[i-1][2...] {
        marks[req] = true
    }
}

print((0..<N).filter{ marks[$0+1] }.reduce(0) { $0 + TKA[$1][0] })
```

# 参考
https://kenkoooo.com/atcoder/#/contest/show/fdc80d97-c9ec-4143-864c-1bc2b49a4650?activeTab=Problems