AtCoder Beginner Contest 335 振り返り

# ABC335
## 概要
https://atcoder.jp/contests/abc335


## A - 202
3

__考えてたこと__
pythonだったら添字を-1にしたらアクセス簡単だけどC++できなかったはず...とか考えながら、文字列の長さから最後の文字の添え字を取得して4に変更しました。

__提出したもの__
```c++:a.cpp
int main() {
    string s;
    cin >> s;
    int last = s.size() - 1;
    s[last] = '4';
    cout << s << endl;
    return 0;
}
```

__振り返り__
解説の一度pop_backしてから4をpush_backするやり方が結構好きでした。まあA問題だし解けたしそれほど気にすることじゃないかな。

## B - Tetrahedral Number
__考えてたこと__
最大でも21の3乗だからあまり気にせずそのまま解けば良いかな、と。for文を小さい数から回せば辞書順も気にする必要なさそうだし。

__提出したもの__
```c++:b.cpp
int main() {
    int n;
    cin >> n;
    for (int i = 0; i <= 21; i++) {
        for (int j = 0; j <= 21; j++) {
            for (int k = 0; k <= 21; k++) {
                if (i + j + k <= n) {
                    cout << i << " " << j << " " << k << endl;
                }
            }
        }
    }
    return 0;
}
```
__振り返り__
大体解説も一緒で特にいうことなし。

## C - Loong Tracking
__考えてたこと__
最初に考えてたのは頭の位置と移動方向さえ保存しておけば他のパーツの座標もわからないかなという考え。ただ、これだと頭以外のパーツはまず頭の合った位置に移動するために最初の方の移動指示の通りに動かないから求まらないことはないけど面倒だということ。
ただ、これを考えながら移動ルート自体は一本線だから頭のスタート地点を(1,0)ではなく(N,0)と考えれば良いのではないかと気づく。

__提出したもの__
```c++:c.cpp
int main() {
    int n, q;
    cin >> n >> q;
    vector<pair<int, int>> head;
    for (int i = n - 1; i >= 0; i--) {
        head.push_back(pair(1 + i, 0));
    }
    rep(i, 0, q) {
        int order;
        cin >> order;
        if (order == 1) {
            char orderDetail;
            cin >> orderDetail;
            switch (orderDetail) {
                case 'R':
                    head.push_back(pair(head[head.size() - 1].first + 1, head[head.size() - 1].second));
                    break;
                case 'L':
                    head.push_back(pair(head[head.size() - 1].first - 1, head[head.size() - 1].second));
                    break;
                case 'U':
                    head.push_back(pair(head[head.size() - 1].first, head[head.size() - 1].second + 1));
                    break;
                case 'D':
                    head.push_back(pair(head[head.size() - 1].first, head[head.size() - 1].second - 1));
                    break;
            }
        } else {
            int orderDetail;
            cin >> orderDetail;
            cout << head[head.size() - orderDetail].first << " " << head[head.size() - orderDetail].second << endl;
        }
    }
    return 0;
}
```

__振り返り__
最初の発想が外れてたけど良かったから思いつけたと思う。ただ、コンテスト外でのんびり時間をかけてやったから、これを本番に思いつけてたかと考えるとかなり怪しそう...。

## D - Loong and Takahashi
__考えてたこと__
問題文の理解に苦労したけど、要は数字をぐるぐる一筆書きで書きたい。
どこかのglidの問題で見た、先に方向を持っておいて(dx,dy)、keyによって向きを変えるのを参考にして、あとはif文で強引に。

__提出したもの__
```c++:d.cpp
int main() {
    int n;
    cin >> n;
    int glid[n][n];

    // direction
    int dx[] = {1, 0, -1, 0};
    int dy[] = {0, 1, 0, -1};
    int directionKey = 0;

    // initialization
    int x = 0;
    int y = 0;
    int num = 1;
    rep(i, 0, n) {
        rep(j, 0, n) {
            glid[i][j] = 0;
        }
    }
    glid[0][0] = 1;

    while (num < n * n) {
        int x_next = x + dx[directionKey];
        int y_next = y + dy[directionKey];
        if (0 <= x_next && 0 <= y_next && x_next < n && y_next < n && glid[y_next][x_next] == 0) {
            num++;
            glid[y_next][x_next] = num;
            x = x_next;
            y = y_next;
        } else {
            directionKey = (directionKey + 1) % 4;
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (j != 0) {
                cout << " ";
            }
            if (glid[i][j] != n * n) {
                cout << glid[i][j];
            } else {
                cout << "T";
            }
            if (j == n - 1) {
                cout << endl;
            }
        }
    }
    return 0;
}
```
__振り返り__
別解がすごかった。あんな感じのぶっとんだ回答が浮かぶ人は素直にすごいなぁと思います。

## 感想
以前、ボロボロなスコアになったこととお仕事で色々合ってモチベが下がっていましたが復活です。
しばらくはコンテストには参加しないでのんびり問題を解いて地力をつけていきたいと思っています。