AOJをC#で解く①〜ITP1_1〜

#はじめに
この記事は僕がC#で解いた[AOJ](https://onlinejudge.u-aizu.ac.jp/home)の問題を解説していく記事です。

まだまだ初学者だけど、プログラムを書く人間として**「なぜその問題に対してそのタイミングでそのコードを書いたのか」**を自分の言葉で説明できることはかなり大事だと思っています。そうじゃないと自分の書いたコードを他のやり方と比較して改善できないし、再現性がない。
なのでこの記事は基本的に、僕が問題を解いた過程や方法を言語として残しておくことを目的としています。そしてそれが誰かのためになれば嬉しいなとすごく思っています。

幾分問題が多いので、これから連続して書いていこうと思います。
今回は[Lesson - ITP1_1](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1)の分だけ書きます。

#ITP1_1
じゃあさっそく書いていきます。
ITP1_1は基礎の基礎なのでほんとに簡単です。

##A問題 - [Hello World] (https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_A)

**問題**
"Hello World" と標準出力にプリントするプログラムを作成してください。

---

**解法**
これはもうシンプルに Hello World と出力するだけなので、特に何かコメントなどはいらないかなと思います。`;`をつけることを忘れないようにぐらいですかね（笑）

```cs:ITP1_1_A.cs
using System;

namespace ITP1_1_A
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Hello World");
        }
    }
}

```



##B問題 - [X Cubic] (https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1)
**問題**
１つの整数 x を読み込んで、x の３乗を計算し結果を出力するプログラムを作成して下さい。

**制約**
1 ≤ x ≤ 100


**数値例**
1)
*input* : 2
*output* : 8

2)
*input* : 3
*output* : 27

---

**解法**
数値を読み込んで2回乗算をするだけです。


```ITP1_1_B.cs
using System;

namespace ITP1_1_B
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = int.Parse(Console.ReadLine());
            int x = i * i * i;
            //べき乗計算はMathクラスのPowメソッドを使う。ex.double result = Math.Pow(2, 3); resultは8
            Console.WriteLine(x);
        }
    }
}

```

**コメント**
なお初心者だとべき乗だと思って`^`を入れることもあると思うんですが(僕がそうでした（笑）)、`^`は排他的論理和の演算子であり、C#にはべき乗のメソッドが別で用意されています。なので今回は2回乗算をしました。
もし数値が大きくなってきて掛け算の繰り返しでは対応できないときはMathクラスのPowメソッドを使います。`Math.Pow(x, y)`でxのy乗を計算します。

##C問題 - [Rectangle](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_C)
**問題**
たて a cm よこ b cm の長方形の面積と周の長さを求めるプログラムを作成して下さい。

**制約**
1 ≤ a, b ≤ 100


**数値例**
*input* : 3 5
*output* : 15 16

面積は 3 × 5 = 15、周の長さは (3 + 5) × 2 = 16です。

---

**解法**
面積の公式は縦×横(= a * b)、周の長さは(縦+横)×2(=(a + b) * 2)なので数値を読み込んでそのとおりに計算していきます。

```ITP1_1_C.cs
using System;
namespace ITP1_1_C
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] str = Console.ReadLine().Split(' ');
            //String.SplitメソッドとはStringクラスメソッドの一つで、文字列を指定した区切り文字で分割し配列に格納する場合に使う

            int a = int.Parse(str[0]);
            int b = int.Parse(str[1]);

            Console.WriteLine(a * b + " " + (a + b) * 2);
        }
    }
}

```
**コメント**
面積と周の長さの公式をちゃんと覚えてたら特に問題はないと思います。
文字列を読み込んで配列を作る時に、`Split(' ')`メソッドはかなりよく使うので覚えておくとよいと思います。文字列を指定した区切り文字で分割するメソッドです。今回の場合は空白で区切っています。

##D問題 - [Watch](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/1/ITP1_1_D)

**問題**
秒単位の時間 S が与えられるので、 h : m : s の形式へ変換して出力してください。ここで、 h は時間、m は60未満の分、s は 60未満の秒とします。


**制約**
0 ≤ S < 86400

**数値例**
*input* : 46979
*output* : 13:2:59

---
**解法**
例えば、150秒は2分(120秒)と30秒に変換できます。この時、150 ÷ 120 = 2 余り 30 となり商の部分が分、余りが秒となります。この商と余りを利用してこの問題は解いていきます。

例題の関係を捉えていくとわかります。
まず46979 ÷ 3600 = 13　余り 179です。続いて、179 ÷ 60 = 2 余り 59 です。よって、46979秒は13時間2分59秒です。
つまり、46979 = 13 × 3600 + 60 × 2 + 59 です。
なお、46979を3600で割った余りを60で割った余りが秒になるということは、46769を60で割った余りが求めたい秒数となります。

よって S / 3600 = h 、 S % 3600 / 60 = m 、 S % 60 = s となります。


```ITP1_1_D.cs
using System;

namespace ITP1_1_D
{
    class Program
    {
        static void Main(string[] args)
        {
            int S = int.Parse(Console.ReadLine());
            int h = S / 3600;
            int m = S % 3600 / 60;
            int s = S % 60;
            Console.WriteLine("{0}:{1}:{2}", h, m, s);
        }
    }
}

```

**コメント**
この問題は公式を覚えておくのでもいいですが、しっかりどういう考え方を理解しておくことが大事だと思います。
あと`("{0}:{1}:{2}", h, m, s)`という書き方はフォーマット出力といって、0の部分にh、1の部分にm、2の部分にsが挿入されて出力されます。


#最後に
ITP1_1の問題は以上です。ITP1_1は簡単なのでさらって解けると思います。
何か指摘などありましたらヨロシクオネガイシマス。