1
0

More than 1 year has passed since last update.

【競プロ/Swift】AtCoder Regular Contest 158

Last updated at Posted at 2023-03-14

注意事項

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

誤答及び、未解答問題

A - +3 +5 +7

問題文
こちら問題ページ

誤答
初めてのARCの出場。
案の定A問題から難しく、TLEでクリアならず。

やっている事としては、
・受け取った値が同じ場合
・期待する値に絶対にならない場合
の例外パターンを先に処理する。

その後に、3つの値が等しくなるまで計算するという処理になっています。

let t = Int(readLine()!)!

func isAllEvenOrOdd(numbers: [Int]) -> Bool {
    var isAllEven = false
    var isAllOdd = false

    numbers.forEach { number in
        if number % 2 == 0 {
            isAllEven = true
        } else {
            isAllOdd = true
        }
    }
    return isAllEven != isAllOdd
}


for _ in 0..<t {
    var xArray = readLine()!.split(separator: " ").map{Int($0)!}
    
    if xArray[0] == xArray[1] && xArray[0] == xArray[2] {
        print(0)
        continue
    }
    
    if !isAllEvenOrOdd(numbers: xArray) {
        print(-1)
        continue
    }
    
    var counter = 0
    while !(xArray[0] == xArray[1] && xArray[0] == xArray[2]) {
        let minIndex = xArray.firstIndex(of: xArray.min()!)!
        let maxIndex = xArray.firstIndex(of: xArray.max()!)!
        let middleIndex = [0, 1, 2].first(where: {$0 != minIndex && $0 != maxIndex})!
        
        xArray[minIndex] += 7
        xArray[maxIndex] += 3
        xArray[middleIndex] += 5
        counter += 1
    }
    print(counter)
}

正答
こちら解説

以上の解説を見ても理解に時間がかかった。
問題をそのまま解くのではなくて、問題の読解・簡略化することが大事だとわかった。

import Foundation
 
func main() {
    let T = Int(readLine()!)!
    for _ in 0..<T {
        let x = readLine()!.split(separator:" ").map{Int($0)!}.sorted()

        // 入力値が全て同じ場合は操作回数0を出力
        if x.allSatisfy({ $0 == x[0] }) {
            print(0)
            continue
        }
        let sumx = x.reduce(0, +)
        let a = sumx / 3

        // 入力値の合計が3の倍数じゃないい場合は、何回操作しても同じ値にならないので、例外パターンの-1を出力
        guard sumx.isMultiple(of: 3) else {
            print(-1)
            continue
        }

        // 正解パターンは3つの入力値とその平均値の偶奇が同じはずなので、割る2した値の数が1以上あると、例外パターンの-1を出力
        guard Set((x + [a]).map({ $0 % 2 })).count == 1 else {
            print(-1)
            continue
        }
        
        // 平均値と今の値の差分の合計(全ての値が等しくなるまで変化しないといけない値の大きさ)を4(一回の操作で変化する値)を割ると、操作回数が出力される。
        let d = x.map({ abs(a - $0)}).reduce(0, +)
        print(d / 4)
    }
}
 
main()

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0