AtCoder Beginner Contest 389 解法解説

A - 9x9

問題概要

1桁の数字同士の乗算結果を求める。

解法

入力文字列から数値を抽出して掛け算する実装を行えばよい。

実装コード

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve() {
    string input;
    cin >> input;
    int a = input[0] - '0';
    int b = input[2] - '0';
    cout << a * b << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

B - tcaF

問題概要

与えられた整数 X が n! に等しいとき、n を出力する。

解法

制約が小さいため、2から順に階乗を計算し、Xと一致するタイミングでインデックスを出力すればよい。

実装コード

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve() {
    int X;
    cin >> X;
    int fact = 1;
    for (int i = 2; ; i++) {
        fact *= i;
        if (fact == X) {
            cout << i << endl;
            return;
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

C - Snake Queue

問題概要

蛇の長さ情報を持つキューを扱う。以下の3種類のクエリを処理する。

  • 長さ l の蛇を末尾に追加
  • 先頭の蛇を削除(後続の蛇の座標が減る)
  • k番目の蛇の先頭座標を出力

解法

全蛇の長さを配列vに格納し、累積和preで座標を管理する。先頭ポインタheadと削除分のオフセットdeltaを用いてクエリを高速に処理する。

実装コード

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve() {
    int Q;
    cin >> Q;
    vector<int> len;
    vector<int> pref = {0};
    int head = 0, offset = 0;

    while (Q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int l;
            cin >> l;
            len.push_back(l);
            pref.push_back(pref.back() + l);
        } else if (type == 2) {
            offset += len[head];
            head++;
        } else {
            int k;
            cin >> k;
            cout << pref[head + k - 1] - offset << endl;
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

D - Squares in Circle

問題概要

無限に敷き詰められた1×1の正方形のタイル上で、タイル中心を半径Rの円の中心とする。円の中に完全に含まれるタイルの個数を求める。

解法

タイルの中心を (0.5, 0.5) としたとき、x軸およびy軸上のタイルは 4(R-1)+1 個固定。残りの領域はx座標を1から順に走査し、各xにおける最大のy座標を求め、小数点以下を切り捨てて4倍して加算する。

実装コード

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 3e5 + 5;

void solve() {
    int R;
    cin >> R;
    int ans = 4 * (R - 1) + 1;

    for (int i = 1; i + 0.5 <= R; i++) {
        double x = i + 0.5;
        double y_max = sqrt(R * R - x * x) - 0.5;
        ans += 4 * (int)y_max;
    }
    cout << ans << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int T = 1;
    while (T--) solve();
    return 0;
}

F - Rated Range

問題概要

N回のレーティング変動が存在する。各変動iは区間 [L_i, R_i] で定義され、この範囲に現在のレーティングが含まれていれば+1される。Q個の初期値Xに対して、N回の変動後のレーティングをそれぞれ求めよ。

解法

(未実装:解法の詳細は今後追記予定)

コンテストページ: https://atcoder.jp/contests/abc389

タグ: AtCoder ABC389 競技プログラミング C++ 累積和

5月28日 14:34 投稿