Submission #55886383


Source Code Expand

use interval_search_for_interactive_problem::{FibonacciSearch, QueryProcesser};
use proconio::{input, source::auto::AutoSource};
use std::io::BufRead;

fn main() {
    let t = read();
    for _ in 0..t {
        solve();
    }
}

fn solve() {
    let n = read();
    let q = QueryProcesser::new();
    let eval_fn = |x, y| x > y;
    let mut solver = FibonacciSearch::new(1, n);
    let ans = solver.solve(q, eval_fn);
    println!("! {ans}");
}

fn read() -> i64 {
    let mut s = "".to_string();
    let stdin = std::io::stdin();
    let mut handle = stdin.lock();
    handle.read_line(&mut s).unwrap();
    let source = AutoSource::from(s.as_str());
    input! {
        from source,
        res: i64,
    }
    res
}

mod interval_search_for_interactive_problem {
    use std::collections::HashMap;

    use crate::read;

    type Output = i64;

    pub struct QueryProcesser {
        pub map: HashMap<i64, Output>,
    }
    impl QueryProcesser {
        pub fn new() -> Self {
            Self {
                map: HashMap::new(),
            }
        }
        fn query(&mut self, i: i64) -> Output {
            if let Some(&x) = self.map.get(&i) {
                x
            } else {
                println!("? {i}");
                let x = read();
                self.map.insert(i, x);
                x
            }
        }
    }

    pub struct FibonacciSearch {
        ml: i64,     // ng_min から分割点の左までの長さ
        mr: i64,     // ng_min から分割点の右までの長さ
        ng_min: i64, // 定義域の最小値 - 1
        ng_max: i64, // 定義域の最大値 + 1
    }

    impl FibonacciSearch {
        /// low: 定義域の最小値
        /// high: 定義域の最大値
        pub fn new(low: i64, high: i64) -> Self {
            Self::build(low, high)
        }

        fn build(low: i64, high: i64) -> Self {
            let (ng_min, ng_max) = (low - 1, high + 1);
            let (mut ml, mut mr) = (1, 1);

            // 探索区間の長さ以上となる最小のフィボナッチ数を求める
            while ml + mr < ng_max - ng_min {
                ml += mr;
                std::mem::swap(&mut ml, &mut mr);
            }

            Self {
                ml,
                mr,
                ng_min,
                ng_max,
            }
        }

        /// eval_fn: eval_fn(x, y) に対して x の方が評価が高いとき true, そうでないとき false を返すclosure
        pub fn solve<F>(&mut self, mut f: QueryProcesser, eval_fn: F) -> Output
        where
            F: Fn(Output, Output) -> bool,
        {
            let mut lval = f.query(self.ng_min + self.ml);
            let mut rval = f.query(self.ng_min + self.mr);

            while self.ml < self.mr {
                self.shrink_interval();

                if eval_fn(lval, rval) {
                    rval = lval;
                    lval = f.query(self.ng_min + self.ml);
                } else {
                    self.ng_min += self.mr;
                    if self.ng_min + self.mr < self.ng_max {
                        lval = rval;
                        rval = f.query(self.ng_min + self.mr);
                    } else {
                        self.shrink_interval();
                        lval = f.query(self.ng_min + self.ml);
                    }
                }
            }

            if eval_fn(lval, rval) {
                lval
            } else {
                rval
            }
        }

        fn shrink_interval(&mut self) {
            self.mr -= self.ml;
            std::mem::swap(&mut self.ml, &mut self.mr);
        }
    }
}

Submission Info

Submission Time
Task 053 - Discrete Dowsing(★7)
User Plan8
Language Rust (rustc 1.70.0)
Score 7
Code Size 3650 Byte
Status AC
Exec Time 23 ms
Memory 4028 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 7 / 7
Status
AC × 2
AC × 34
Set Name Test Cases
Sample 01_sample_01.txt, 01_sample_02.txt
All 01_sample_01.txt, 01_sample_02.txt, 02_fixed_02.txt, 03_small_01.txt, 03_small_02.txt, 03_small_03.txt, 03_small_04.txt, 03_small_05.txt, 03_small_06.txt, 03_small_07.txt, 03_small_08.txt, 03_small_09.txt, 03_small_10.txt, 04_deterministic_01.txt, 04_deterministic_02.txt, 04_deterministic_03.txt, 04_deterministic_04.txt, 04_deterministic_05.txt, 04_deterministic_06.txt, 04_deterministic_07.txt, 04_deterministic_08.txt, 04_deterministic_09.txt, 04_deterministic_10.txt, 05_adaptive_01.txt, 05_adaptive_02.txt, 05_adaptive_03.txt, 05_adaptive_04.txt, 05_adaptive_05.txt, 05_adaptive_06.txt, 05_adaptive_07.txt, 05_adaptive_08.txt, 05_adaptive_09.txt, 05_adaptive_10.txt, 06_edge_01.txt
Case Name Status Exec Time Memory
01_sample_01.txt AC 5 ms 3832 KiB
01_sample_02.txt AC 2 ms 3856 KiB
02_fixed_02.txt AC 2 ms 3836 KiB
03_small_01.txt AC 14 ms 3916 KiB
03_small_02.txt AC 14 ms 3792 KiB
03_small_03.txt AC 14 ms 3824 KiB
03_small_04.txt AC 14 ms 3808 KiB
03_small_05.txt AC 14 ms 3872 KiB
03_small_06.txt AC 3 ms 3664 KiB
03_small_07.txt AC 3 ms 3792 KiB
03_small_08.txt AC 3 ms 3796 KiB
03_small_09.txt AC 4 ms 3664 KiB
03_small_10.txt AC 3 ms 3844 KiB
04_deterministic_01.txt AC 23 ms 3848 KiB
04_deterministic_02.txt AC 23 ms 3832 KiB
04_deterministic_03.txt AC 23 ms 3836 KiB
04_deterministic_04.txt AC 23 ms 4024 KiB
04_deterministic_05.txt AC 23 ms 3956 KiB
04_deterministic_06.txt AC 23 ms 4004 KiB
04_deterministic_07.txt AC 22 ms 3800 KiB
04_deterministic_08.txt AC 23 ms 4028 KiB
04_deterministic_09.txt AC 23 ms 4004 KiB
04_deterministic_10.txt AC 22 ms 3828 KiB
05_adaptive_01.txt AC 5 ms 3676 KiB
05_adaptive_02.txt AC 5 ms 3728 KiB
05_adaptive_03.txt AC 6 ms 3920 KiB
05_adaptive_04.txt AC 5 ms 3792 KiB
05_adaptive_05.txt AC 5 ms 3924 KiB
05_adaptive_06.txt AC 5 ms 3772 KiB
05_adaptive_07.txt AC 6 ms 3860 KiB
05_adaptive_08.txt AC 6 ms 3668 KiB
05_adaptive_09.txt AC 6 ms 3848 KiB
05_adaptive_10.txt AC 6 ms 3848 KiB
06_edge_01.txt AC 3 ms 3772 KiB