https://atcoder.jp/contests/abc391/tasks/abc391_f
A, B, Cを降順に並べ直すと、と取れば
が最も大きくなります。その次は、
のどれかになります。PriorityQueueを使えば簡単にK番目を求められます。
PriorityQueueに重複してTripletを入れてはいけないのでHashSetを使っています。TripletをHashSetのキーにするには、Hash traitを実装すればよいです。
// K-th Largest Triplet #![allow(non_snake_case)] use std::collections::{BinaryHeap, HashSet}; use std::hash::{Hash, Hasher}; //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } //////////////////// Triplet //////////////////// #[derive(Clone, Copy, Eq, PartialEq)] struct Triplet { i: usize, j: usize, k: usize, value: i64 } impl Ord for Triplet { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.value.cmp(&other.value) } } impl PartialOrd for Triplet { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) } } impl Hash for Triplet { fn hash<H: Hasher>(&self, state: &mut H) { self.i.hash(state); self.j.hash(state); self.k.hash(state); } } impl Triplet { fn new(i: usize, j: usize, k: usize, A: &Vec<i64>, B: &Vec<i64>, C: &Vec<i64>) -> Triplet { let value = A[i] * B[j] + B[j] * C[k] + C[k] * A[i]; Triplet { i, j, k, value } } } //////////////////// process //////////////////// fn read_input() -> (usize, Vec<i64>, Vec<i64>, Vec<i64>) { let v: Vec<usize> = read_vec(); let K = v[1]; let A: Vec<i64> = read_vec(); let B: Vec<i64> = read_vec(); let C: Vec<i64> = read_vec(); (K, A, B, C) } fn nexts(t: Triplet, A: &Vec<i64>, B: &Vec<i64>, C: &Vec<i64>) -> Vec<Triplet> { let N = A.len(); let mut ts: Vec<Triplet> = vec![]; if t.i < N - 1 { ts.push(Triplet::new(t.i+1, t.j, t.k, &A, &B, &C)) } if t.j < N - 1 { ts.push(Triplet::new(t.i, t.j+1, t.k, &A, &B, &C)) } if t.k < N - 1 { ts.push(Triplet::new(t.i, t.j, t.k+1, &A, &B, &C)) } ts } fn F(K: usize, mut A: Vec<i64>, mut B: Vec<i64>, mut C: Vec<i64>) -> i64 { A.sort_by(|a, b| b.cmp(&a)); B.sort_by(|a, b| b.cmp(&a)); C.sort_by(|a, b| b.cmp(&a)); let mut tree = BinaryHeap::new(); let t0 = Triplet::new(0, 0, 0, &A, &B, &C); tree.push(t0); let mut queued = HashSet::new(); queued.insert(t0); for _ in 0..K-1 { let t = tree.pop().unwrap(); for t1 in nexts(t, &A, &B, &C) { if !queued.contains(&t1) { tree.push(t1); queued.insert(t1); } } } let t =tree.pop().unwrap(); t.value } fn main() { let (K, A, B, C) = read_input(); println!("{}", F(K, A, B, C)) }