結果

問題 No.3246 80% Accuracy Calculator
ユーザー urectanc
提出日時 2025-08-23 00:21:14
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 107 ms / 2,000 ms
コード長 2,122 bytes
コンパイル時間 13,379 ms
コンパイル使用メモリ 396,496 KB
実行使用メモリ 25,996 KB
平均クエリ数 2056.58
最終ジャッジ日時 2025-08-23 00:21:46
合計ジャッジ時間 19,764 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 43
権限があれば一括ダウンロードができます

ソースコード

diff #

use std::{collections::HashMap, process::exit};

use proconio::input_interactive;

const K: usize = 100;

fn main() {
    let query = |q: &Query| {
        match q {
            Query::Ask(register) => println!("? {register}"),
            Query::Add(src1, src2, dst) => println!("+ {src1} {src2} {dst}"),
            Query::Ans(register) => {
                println!("! {register}");
                exit(0);
            }
        }

        input_interactive! { res: isize }
        assert_ne!(res, -1);

        res as usize
    };

    let read = |register: char| {
        let mut counter = HashMap::new();
        let read_query = Query::Ask(register);
        for _ in 0..K {
            let res = query(&read_query);
            *counter.entry(res).or_insert(0) += 1;
        }

        let &v = counter.iter().max_by_key(|t| t.1).unwrap().0;
        v
    };

    let write = |src1: char, src2: char, dst: char, expected: usize| {
        let write_query = Query::Add(src1, src2, dst);

        loop {
            query(&write_query);

            let val = read(dst);
            if val == expected {
                break;
            }
        }
    };

    let free_register = |ban1: char, ban2: char| {
        ['A', 'B', 'C']
            .iter()
            .find(|&&c| c != ban1 && c != ban2)
            .copied()
            .unwrap()
    };

    let x = read('A');
    let mut y = read('B');
    write('A', 'C', 'B', x);

    let mut ans_register = 'A';
    let mut pow_register = 'B';
    let mut ans = x;
    let mut pow = x;
    y -= 1;
    while y > 0 {
        if y & 1 == 1 {
            let dst = free_register(ans_register, pow_register);
            ans += pow;
            write(ans_register, pow_register, dst, ans);
            ans_register = dst;
        }

        let dst = free_register(ans_register, pow_register);
        pow += pow;
        write(pow_register, pow_register, dst, pow);
        pow_register = dst;

        y >>= 1;
    }

    let ans_query = Query::Ans(ans_register);
    query(&ans_query);
}

enum Query {
    Ask(char),
    Add(char, char, char),
    Ans(char),
}
0