Мне интересно, чего вы пытаетесь достичь, используя сложные структуры данных, такие как PriorityQueue
и Deque
, для решения такой проблемы, как эта. Это можно решить с помощью пары вложенных циклов:
for {
i <- 2 to I
j <- 1 until i
if i != j && P(i-1) + P(j - 1) == C
} println("Case #%d: %d %d" format (n, j, i))
Хуже линейного, лучше квадратичного. Поскольку элементы не отсортированы, и для их сортировки потребуется O(nlogn)
, вы не сможете добиться намного большего, чем это, насколько я вижу.
На самом деле, сказав все это, я теперь нашел способ сделать это за линейное время. Хитрость в том, что для каждого найденного числа p
вы знаете, каково его дополнение: C - p
. Я ожидаю, что есть несколько способов исследовать это - я до сих пор думал о двух.
Одним из способов является создание карты с O(n)
характеристиками, такими как растровое изображение или хэш-карта. Для каждого элемента укажите его индекс. Тогда нужно только найти элемент, для которого его дополнение также имеет запись на карте. Тривиально, это может быть так же просто, как это:
val PM = P.zipWithIndex.toMap
val (p, i) = PM find { case (p, i) => PM isDefinedAt C - p }
val j = PM(C - p)
Однако это не сработает, если число равно его дополнению. Другими словами, если есть два p
таких, что p + p == C
. Таких случаев в примерах немало. Затем можно проверить это условие, а затем просто использовать indexOf
и lastIndexOf
- за исключением того, что возможно, что существует только один p
, такой что p + p == C
, и в этом случае это тоже не будет ответом.
Итак, я закончил чем-то более сложным, которое проверяет существование дополнения в то же время, когда строится карта. Вот полное решение:
import scala.io.Source
object StoreCredit3 extends App {
val source = if (args.size > 0) Source fromFile args(0) else Source.stdin
val input = source getLines ()
val N = input.next.toInt
1 to N foreach { n =>
val C = input.next.toInt
val I = input.next.toInt
val Ps = input.next split ' ' map (_.toInt)
val (_, Some((p1, p2))) = Ps.zipWithIndex.foldLeft((Map[Int, Int](), None: Option[(Int, Int)])) {
case ((map, None), (p, i)) =>
if (map isDefinedAt C - p) map -> Some(map(C - p) -> (i + 1))
else (map updated (p, i + 1), None)
case (answer, _) => answer
}
println("Case #%d: %d %d" format (n, p1, p2))
}
}