【ABC163へ参加してみた】在宅勤務になったのでマネジメント系SEが競技プログラミング始めてみた。#1 -解説-

#前回の記事
前回はAtCoderに参加した私の結果や反省を報告しました。
[【ABC163へ参加してみた】在宅勤務になったのでマネジメント系SEが競技プログラミング始めてみた。#1
](https://qiita.com/makom/items/ddd0a6424326496b535a)

(需要があるかは全く分かりませんが)
今回の記事では私が解答できたＡＢＣ問題について解説します。

#Ａ問題：[＜A - Circle Pond＞](https://atcoder.jp/contests/abc163/tasks/abc163_a)

<details><summary>問題文抜粋</summary>
<img width="364" alt="スクリーンショット 2020-04-20 16.28.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/178e3833-ad93-fe27-05bf-9a0933da74ef.png">
</details>

###解説
円周を求める問題です。
円周は**直径×円周率**で求めることができますね。
直径については、入力値で半径を取得することができるのでOK！！
あと必要な**円周率**ですが以下のように**cmath**を取り込むことで**M_PI**が使用できます。

```C++:problemA.cpp
#include <iostream>
#include <cmath>

using namespace std;

int main(int argc, const char * argv[]) {

    int r;
    cin >> r;

    cout << 2*r*M_PI << endl; //M_PIは円周率

    return 0;    
}
```

問題分をよく読むと、以下の記載があります。
<img width="853" alt="スクリーンショット 2020-04-20 16.35.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/85cb672f-852f-c3fa-c1dc-98340b3c5384.png">

そのため**M_PI**を使用せずとも学生時代にならった方も多い**円周率=3.14**を用いることもできます。

#Ｂ問題：[＜B - Homework＞](https://atcoder.jp/contests/abc163/tasks/abc163_b)
<details><summary>問題文抜粋</summary>
<img width="832" alt="スクリーンショット 2020-04-20 16.47.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/35b89f52-f3bd-fb29-90e1-140365583e6b.png">
</details>

###解説
図に書くとイメージがつきやすいと思います。
<img width="480" alt="スクリーンショット 2020-04-20 16.49.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/0f1f34ea-f393-f222-1c4b-61a0a8c5d593.png">

ということは全ての宿題を終えるためにはこんなイメージになるのがわかると思います。
<img width="797" alt="スクリーンショット 2020-04-20 16.50.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/b4a93af8-aa6f-e09d-7f26-4d92881db855.png">

あと必要なのは「高橋君が夏休み(N日)の間に宿題を終えることができるのか」を判定することです。

```C++:problemB.cpp
#include <iostream>
 
using namespace std;
 
int main(int argc, const char * argv[]) {
 
    int n,m;
    cin >> n >> m;
 
    int a[m];
    for(int i=0; i<m; i++) cin >> a[i];
    
    int total = 0;
    
    for(int i=0; i<m; i++){
        total += a[i]; //宿題日数を足し合わせ
    }
    
    int judge = n-total; //夏休みの日数から宿題のトータル日数をマイナス
    
    if(judge<0) //はたして高橋君は宿題を終えることができるのか。。
        cout << "-1" << endl;
    else
        cout << judge << endl;
    
    return 0;
    
}
```

#Ｃ問題：[＜C - management＞](https://atcoder.jp/contests/abc163/tasks/abc163_c)
<details><summary>問題文抜粋</summary>
<img width="1023" alt="スクリーンショット 2020-04-20 17.05.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/6d5a4ce0-58bd-61a9-b83f-15541deb235a.png">
</details>
###解説
こちらもＢ問題と同じく図に書くとわかると思います。
<img width="666" alt="スクリーンショット 2020-04-20 17.07.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/ed2fe149-fb8b-3c87-4be8-3dbdba8d2451.png">

実際の入力例を元にもう少しイメージを膨らませます。
<img width="1111" alt="スクリーンショット 2020-04-20 17.08.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/b6e5e7e9-6279-7262-eae9-1ac94bbd67f6.png">
この入力例の際には以下のような関係性になっています。
<img width="584" alt="スクリーンショット 2020-04-20 17.14.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/5373cab0-da12-7fa3-320f-ea8226d7e5a3.png">

これだけだと私も当日あんまりイメージわかなかったので、
もう一段階として実際に上司と部下の関係をピラミッド的に書いてみます。
<img width="484" alt="スクリーンショット 2020-04-20 17.10.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509729/5af238ea-1b8a-3107-5484-45cdc61d6aab.png">
これでイメージついたでしょうか？？
重要な点は**社員番号#1の人は必ず部下がいる(上司である)**ということです。

これらをふまえてコードを記載します。

```C++:problemC.cpp
#include <iostream>

using namespace std;

int main(int argc, const char * argv[]) {

    int n;
    cin >> n;

    int a[n];
    a[1] = 0; //社員番号#1(a[1])は一番偉いから上司はいない
    
    for(int i=2; i<=n; i++) cin >> a[i]; //社員番号#2〜#Nの上司の人数を入力
    
    int ans[n];
    for(int i=1; i<=n; i++) ans[i] = 0; //配列の初期化
    
    int tmp;
    
    for(int i=1; i<=n; i++){
        tmp = a[i];
        ans[tmp]++; //社員番号#iの上司である人の社員番号a[i]をカウント
    }
    
    for(int i=1; i<=n; i++) cout << ans[i] << endl; //カウントした結果を出力
    
    return 0;
    
}
```

#最後に
いかがだったでしょうか？
解説を記載するのも初めてなので、見ても解らないやもう少しこうすると良いのではないか？といった暖かい言葉ドシドシお待ちしています。