Problem:
Score : 400 points

Problem Statement

Let {\rm comb}(n,r) be the number of ways to choose r objects from among n objects, disregarding order.
From n non-negative integers a_1, a_2, ..., a_n, select two numbers a_i > a_j so that {\rm comb}(a_i,a_j) is maximized.
If there are multiple pairs that maximize the value, any of them is accepted.

Constraints

2 \leq n \leq 10^5

0 \leq a_i \leq 10^9

a_1,a_2,...,a_n are pairwise distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

n
a_1 a_2 ... a_n

Output

Print a_i and a_j that you selected, with a space in between.

Sample Input 1

5
6 9 4 2 11

Sample Output 1

11 6

\rm{comb}(a_i,a_j) for each possible selection is as follows:

\rm{comb}(4,2)=6

\rm{comb}(6,2)=15

\rm{comb}(6,4)=15

\rm{comb}(9,2)=36

\rm{comb}(9,4)=126

\rm{comb}(9,6)=84

\rm{comb}(11,2)=55

\rm{comb}(11,4)=330

\rm{comb}(11,6)=462

\rm{comb}(11,9)=55

Thus, we should print 11 and 6.

Sample Input 2

2
100 0

Sample Output 2

100 0

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::cmp::max;

pub struct Comb {
    max: usize,
    m: i64,
    fac: Vec<i64>,
    finv: Vec<i64>,
}
impl Comb {
    /// initialize table
    /// max: maximum that n as nCk takes
    /// m: MOD, a prime number
    /// O(n)
    pub fn new(max: usize, m: i64) -> Comb {
        let n = max;
        let mut fac = Vec::with_capacity(n);
        fac.push(1);
        fac.push(1);
        let mut finv = Vec::with_capacity(n);
        finv.push(1);
        finv.push(1);
        let mut inv = Vec::with_capacity(n);
        inv.push(1);
        inv.push(1);
        for i in 2..n {
            let i = i as i64;
            let tmp = fac.last().unwrap() * i % m;
            fac.push(tmp);
            let tmp = m - inv[(m % i) as usize] * (m / i) % m;
            inv.push(tmp);
            let tmp = finv.last().unwrap() * inv.last().unwrap() % m;
            finv.push(tmp);
        }
        Comb {
            max: max,
            m: m,
            fac: fac,
            finv: finv,
        }
    }
    /// nCr
    pub fn ncr(&self, n: usize, k: usize) -> i64 {
        // since n, k are usize, do not need to check `n < 0 || k < 0`
        if n < k || n > self.max {
            panic!("Invalid query (n, k) = ({}, {})", n, k);
        } else {
            self.fac[n] * (self.finv[k] * self.finv[n - k] % self.m) % self.m
        }
    }
}

use std::cmp::min;

fn main() {
    let n: usize = read();
    let mut a: Vec<i64> = vec![];
    let mut maxv = 0;
    let mut ansx = 0;
    let mut ansy = 0;

    for i in 0..n {
        let ai = read();
        if maxv < ai {
            maxv = ai;
            ansx = ai;
        }
        a.push(ai);
    }

    let mut dist = std::i64::MAX;

    for i in 0..a.len() {
        let ai = a[i];
        if ai == maxv {
            continue;
        }
        let mut ad = 0;
        if maxv % 2 == 0 {
            ad = ((maxv / 2) - ai).abs();
        } else {
            ad = min(((maxv - 1) / 2 - ai).abs(), ((maxv + 1) / 2 - ai).abs());
        }
        if ad < dist {
            ansy = ai;
            dist = ad;
        }
    }
    println!("{} {}", ansx, ansy);

    // let mut ans = 0;
    //
    // for i in 0..n {
    //     let ai = a[i];
    //     println!("{} {}", ai, maxv);
    //     println!("result{}", result);
    //     ans = max(ans, result);
    // }
    // println!("{}", ans);
}