プログラミングとか色々

プログラミングとかについて色々

【AtCoder】ABC192復習【Rust】

A問題

解法

 100の倍数ごとにご褒美がもらえるため、100で割ったあまりのみを考えれば良い。100から100で割ったあまりを引くことで、次の100の倍数までの数が求まる。

ソースコード

use proconio::{fastout, input};

#[fastout]
fn main() {
    input! { n: isize };

    println!("{}", 100 - n % 100);
}

B問題

解法

 問題文の「先頭から奇数番目の文字が全て英小文字であり、かつ、先頭から偶数番目の文字が全て英大文字である」をそのまま実装する。文字列を読み取り文字に分解し、すべてがこの条件を満たすとき"Yes"を、そうでないとき、"No"を出力する。

注意点

1based-indexと0besed-indexで偶数と奇数が変わる。

ソースコード

use proconio::{fastout, input};

#[fastout]
fn main() {
    input! {
        s: String
    };

    let ans = s
        .chars()
        .zip(1..)
        .all(|(c, i)| (i % 2 == 1 && c.is_lowercase()) || (i % 2 == 0 && c.is_uppercase()));

    println!("{}", if ans { "Yes" } else { "No" });
}

C問題

解法

 問題文の $g_1(x), g_2(x), f(x)$ を実装しfor文で回す。Kが十分小さいので間に合う。計算量 $O(N)$

桁を並び替えるとき、nを10で割ったあまりを求めその後nを10で割った値に更新していくことで、各桁の数字を入れた配列を作ることができる。文字列と相互に変換する方法もできそう。

ソースコード

use proconio::{fastout, input};

#[fastout]
fn main() {
    input! {
        n: isize,
        k: isize
    };

    let f = |mut n: isize| -> isize {
        let mut a = Vec::new();
        while n != 0 {
            a.push(n % 10);
            n /= 10;
        }
        a.sort();
        let g1 = a
            .iter()
            .zip(0..)
            .fold(0, |sum, (x, i)| sum + x * 10isize.pow(i));
        a.reverse();
        let g2 = a
            .iter()
            .zip(0..)
            .fold(0, |sum, (x, i)| sum + x * 10isize.pow(i));
        g1 - g2
    };
    let mut ans = n;
    for _ in 0..k {
        ans = f(ans);
    }

    println!("{}", ans);
}