結果

問題 No.1515 Making Many Multiples
ユーザー LyricalMaestroLyricalMaestro
提出日時 2024-12-30 21:49:38
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 1,457 ms / 2,000 ms
コード長 4,617 bytes
コンパイル時間 16,655 ms
コンパイル使用メモリ 379,772 KB
実行使用メモリ 64,640 KB
最終ジャッジ日時 2024-12-30 21:50:54
合計ジャッジ時間 35,882 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 1,419 ms
64,640 KB
testcase_03 AC 1,423 ms
64,640 KB
testcase_04 AC 1,408 ms
63,744 KB
testcase_05 AC 1,457 ms
64,640 KB
testcase_06 AC 846 ms
64,640 KB
testcase_07 AC 1,030 ms
64,640 KB
testcase_08 AC 352 ms
15,872 KB
testcase_09 AC 772 ms
31,488 KB
testcase_10 AC 755 ms
33,408 KB
testcase_11 AC 1,028 ms
44,544 KB
testcase_12 AC 593 ms
27,264 KB
testcase_13 AC 16 ms
5,248 KB
testcase_14 AC 1,167 ms
49,920 KB
testcase_15 AC 19 ms
5,248 KB
testcase_16 AC 1,365 ms
59,648 KB
testcase_17 AC 229 ms
32,768 KB
testcase_18 AC 155 ms
43,008 KB
testcase_19 AC 33 ms
20,352 KB
testcase_20 AC 240 ms
19,328 KB
testcase_21 AC 865 ms
62,208 KB
testcase_22 AC 3 ms
5,248 KB
testcase_23 AC 926 ms
62,592 KB
testcase_24 AC 1 ms
5,248 KB
testcase_25 AC 1 ms
5,248 KB
testcase_26 AC 1 ms
5,248 KB
testcase_27 AC 1,296 ms
62,720 KB
testcase_28 AC 671 ms
63,360 KB
testcase_29 AC 22 ms
5,248 KB
testcase_30 AC 64 ms
5,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

use std::io;

fn main() {
    // Pythonコードの MIN_VALUE に対応
    const MIN_VALUE: i64 = -1_000_000_000_000_000_000;

    // 入力の受け取り (1行目: N, K, X, Y)
    let mut input_str = String::new();
    io::stdin().read_line(&mut input_str).unwrap();
    let mut it = input_str.split_whitespace();
    let n: usize = it.next().unwrap().parse().unwrap(); // N
    let k: usize = it.next().unwrap().parse().unwrap(); // K
    let x: i64 = it.next().unwrap().parse().unwrap();   // X
    let y: i64 = it.next().unwrap().parse().unwrap();   // Y

    // 入力の受け取り (2行目: A の要素)
    input_str.clear();
    io::stdin().read_line(&mut input_str).unwrap();
    let a_list: Vec<i64> = input_str
        .split_whitespace()
        .map(|s| s.parse().unwrap())
        .collect();
    assert_eq!(a_list.len(), n);

    // dp, update_dp を 2次元配列で確保 (初期値は MIN_VALUE)
    let mut dp = vec![vec![MIN_VALUE; k]; k];
    let mut update_dp = vec![vec![MIN_VALUE; k]; k];

    // X%K, Y%K の剰余は負数対策込みで安全に取る
    let x_mod = ((x % k as i64) + k as i64) as usize % k;
    let y_mod = ((y % k as i64) + k as i64) as usize % k;

    // dp[x_mod][y_mod] = 0, dp[y_mod][x_mod] = 0
    dp[x_mod][y_mod] = 0;
    dp[y_mod][x_mod] = 0;

    // max_dp_x, max_dp_y を定義(初期値はすべて MIN_VALUE)
    let mut max_dp_x = vec![MIN_VALUE; k];
    let mut max_dp_y = vec![MIN_VALUE; k];
    // Python同様、X%K, Y%K の位置は 0 で初期化
    max_dp_x[x_mod] = 0;
    max_dp_x[y_mod] = 0;
    max_dp_y[x_mod] = 0;
    max_dp_y[y_mod] = 0;

    // Pythonコードの answer (とりあえず i64 で扱う)
    let mut answer: i64 = 0;

    // --- A の各要素ごとにループ ---
    for &a in &a_list {
        // a_ = a % K (負対策込み)
        let a_ = ((a % k as i64) + k as i64) as usize % k;

        // Python でいう array = [] (更新対象の (x,y) を一時保存するベクタ)
        let mut update_pairs = Vec::new();

        // 1) 結局 A を捨てるもの
        //    for k_y in range(K):
        //        k_x_ = (-a_ - k_y) % K
        //        update_dp[k_x_][k_y] = dp[k_x_][k_y] + 1
        //        array.append((k_x_, k_y))
        for k_y in 0..k {
            let ky_i64 = k_y as i64;
            let a_i64 = a_ as i64; 
            let kx_ = (((-a_i64) - ky_i64) % (k as i64) + k as i64) as usize % k;

            update_dp[kx_][k_y] = dp[kx_][k_y].saturating_add(1);
            update_pairs.push((kx_, k_y));
        }

        // 2) for k_y in range(K):
        //       k_x_ = (- a_ - k_y) % K
        //       update_dp[a_][k_y] = max(
        //           update_dp[a_][k_y], dp[a_][k_y], dp[k_x_][k_y] + 1, max_dp_y[k_y]
        //       )
        //       array.append((a_, k_y))
        for k_y in 0..k {
            let ky_i64 = k_y as i64;
            let a_i64 = a_ as i64;
            let kx_ = (((-a_i64) - ky_i64) % (k as i64) + k as i64) as usize % k;

            // 4つの候補の最大をとる
            let candidate = update_dp[a_][k_y]
                .max(dp[a_][k_y])
                .max(dp[kx_][k_y].saturating_add(1))
                .max(max_dp_y[k_y]);

            update_dp[a_][k_y] = candidate;
            update_pairs.push((a_, k_y));
        }

        // 3) for k_x in range(K):
        //       k_y_ = (- a_ - k_x) % K
        //       update_dp[k_x][a_] = max(
        //           update_dp[k_x][a_], dp[k_x][a_], dp[k_x][k_y_] + 1, max_dp_x[k_x]
        //       )
        //       array.append((k_x, a_))
        for k_x in 0..k {
            let kx_i64 = k_x as i64;
            let a_i64 = a_ as i64;
            let ky_ = (((-a_i64) - kx_i64) % (k as i64) + k as i64) as usize % k;

            let candidate = update_dp[k_x][a_]
                .max(dp[k_x][a_])
                .max(dp[k_x][ky_].saturating_add(1))
                .max(max_dp_x[k_x]);

            update_dp[k_x][a_] = candidate;
            update_pairs.push((k_x, a_));
        }

        // 4) 更新を dp に反映 + max_dp_x, max_dp_y, answer を更新
        for (xx, yy) in update_pairs {
            if dp[xx][yy] < update_dp[xx][yy] {
                dp[xx][yy] = dp[xx][yy].max(update_dp[xx][yy]);
                max_dp_x[xx] = max_dp_x[xx].max(dp[xx][yy]);
                max_dp_y[yy] = max_dp_y[yy].max(dp[xx][yy]);
                answer = answer.max(dp[xx][yy]);
            }
            // update_dp をリセット
            update_dp[xx][yy] = MIN_VALUE;
        }
    }

    // Python での print(answer) に対応
    println!("{}", answer);
}
0