1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AtCoder Beginner Contest 336 振り返り

Posted at

ABC336

概要

実力的には二年前に茶色になって放置して暫くぶりの参加なので詳しい解説などは期待しないでもらえると。
同じぐらいの初心者さんがこんな感じで解いたのかぁ的な見方か、上級者の方が愉悦として見ていただけると幸いです。

A - Long Loong

考えてたこと
特になし

提出したもの

a.cpp
int main() {
    int n;
    cin >> n;
    string ans;
    ans += "L";
    rep(i, 0, n) {
        ans += "o";
    }
    ans += "ng";
    cout << ans << endl;
    return 0;
}

振り返り
特になし

B - CTZ

考えてたこと
10進数の数字をn進数に直すみたいなの、高校の時やった覚えがあります。
2で割っていってどこまで余りが出ないか数えるだけ。
提出したもの

b.cpp
int main() {
    int n;
    cin >> n;
    int ans = 0;
    while (true) {
        if (n % 2 == 0) {
            ans++;
            n /= 2;
        } else
            break;
    }
    cout << ans << endl;
    return 0;
}

振り返り
bitを用いるやり方や、countr_zeroを用いるやり方など解説から勉強。

C - Even Digits

考えてたこと
出力例の値がかなり大きかったから普通に解く問題じゃないだろうなぁと予想。
B問題でやったみたいにn進数の余りをうまく使ったら解けそうと判断。
先に良い整数を小さい順に配列で持っておいてn進数の余りをkeyとして持ってきてそれを1の位から並べていく、それだけ。

提出したもの

c.cpp
int main() {
    ll num;
    cin >> num;
    num--;
    ll ans = 0;
    int goodNum[] = {0, 2, 4, 6, 8};
    ll numTimes = 1;
    while (num > 0) {
        ll a = num % 5;
        ans += goodNum[a] * numTimes;

        num /= 5;
        numTimes *= 10;
    }
    cout << ans << endl;
    return 0;
}

振り返り
実際に掛け算をして値を求めてたけど、回答を見てそもそも計算する必要もないと気づきました。文字列として小さい桁から順に数字を持って最後にreverseするやり方の方が桁の値が大きくても良いし計算もしなくて安全。問題作成者の性格次第でLLでも回答範囲外に出来るから正直危なかったかも、反省。

D - Pyramid

考えてたこと
全然わかりませんでした。
解答読んだらかなり純粋な算数?数学?でびっくりしました。
youtubeの公式解説のdr[i]=min(dr[i+1]+1,vec)みたいな解き方が好きで解説を聞いている途中で一回自分で書いてみたらACしました。

提出したもの

d.cpp
int main() {
    int n;
    cin >> n;
    vector<int> vec(n);
    rep(i, 0, n) cin >> vec[i];

    vector<int> max_left(n);
    vector<int> max_right(n);

    for (int i = 0; i < n; i++) {
        if (i == 0) {
            max_left[i] = 1;
        } else {
            max_left[i] = min(max_left[i - 1] + 1, vec[i]);
        }
    }

    for (int i = n - 1; 0 <= i; i--) {
        if (i == n - 1) {
            max_right[i] = 1;
        } else {
            max_right[i] = min(max_right[i + 1] + 1, vec[i]);
        }
    }

    int ans = 0;
    for (int i = 0; i < n; i++) {
        int now_ans = min(max_left[i], max_right[i]);
        ans = max(ans, now_ans);
    }
    cout << ans << endl;
    return 0;
}

振り返り
パワーで解くやり方なら気づけたかもだから反省、諦めずに。

感想

D問題でかなり詰まってたので、解説を見たら楽しくなってモチベがちょっと復活してきました。わくわくです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?