AtCoder Beginner Contest 170 D - Not Divisible
考え方
エラトステネスの篩が思い浮かべばほぼ勝ち。こういうときはAiから考えがちではあるが、Ajから考えるとよい。
- (1 <= j <= N)について、Ajを除くAjの倍数はダメ
- それぞれの数について、2個以上含まれている場合はダメ
これらを、与えられた数列の各要素においてチェックする 。
実装
制約を見るとAi <= 106なため、予めBooleanArray(A_max)を用意してチェックを行うことができる。また、同じ数を2回チェックしたことを検出するためにもう一つBooleanArrayを用意する。
val dp = BooleanArray(max + 1) { true } //1つ目の条件用配列 val searched = BooleanArray(max + 1) { false } //2つ目の条件用配列
各要素Aiのチェック時に、
- その数を除いた倍数をA_maxを超えるまでdpをfalseに
- 一回目のチェックでsearchedをtrueに、2回目以降にチェックした場合はその数のdpをfalseに
という感じ。
A.forEach { it -> val a = it if (searched[a]) { dp[a] = false return@forEach } searched[a] = true var i = a * 2 while (i <= max) { dp[i] = false i += a } }
最後にdpがtrueの要素を数える
A.filter { a ->
dp[a]
}.size.let {
println(it)
}