AOJをC#で解く④~ITP1_4~

#はじめに
前回の記事は[AOJをC#で解く③~ITP1_3~](https://qiita.com/hikarutakenouch/items/04b98de967adb1267f15)です。
while文やfor文などの繰り返し処理について書きました。


今回は[ITP1_4](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/4)です。
ITP1_4は計算における演算子を取り扱います。

#A問題 - [A/B Problem](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/4/ITP1_4_A)

**問題**
２つの整数 a と b を読み込んで、以下の値を計算するプログラムを作成して下さい：

- a ÷ b ： d (整数)
- a ÷ b の余り ： r (整数)
- a ÷ b ： f (浮動小数点数)

fについては、0.00001以下の誤差があってもよいものとします。

**制約**
1 ≤ a, b ≤ 10^9

**数値例**
*input* : 3 2
*output* : 1 1 1.50000

---
**解法**
読み込んだ数値に対して問題通りに計算するだけですが、型の扱いに注意しましょう。

- a ÷ b ： d (整数)
- a ÷ b の余り ： r (整数)
- a ÷ b ： f (浮動小数点数)

とあるので、dとrは整数なのでint型で問題ないですが、fは浮動小数点数で、制約が 1 ≤ a, b ≤ 10^9 なので、double型にaとbを変換して計算する必要があります。

「fについては、0.00001以下の誤差があってもよいものとします。」という注意書きがあるので、fは小数点5位まで出力させたいので、 `f.ToString("f5")` と書きます。fの次の数字で小数点何位までかを指定します。たまに使う書き方なので覚えておきましょう。

```ITP1_4_A.cs
using System;

class Program
{
    static void Main()
    {
        string[] i = Console.ReadLine().Split(' ');
        int a = int.Parse(i[0]);
        int b = int.Parse(i[1]);

        int d = a / b;
        int r = a % b;
        double f = (double)a / b;

        Console.WriteLine("{0} {1} {2}", d, r, f.ToString("f5"));
    }
}

```

**コメント**
浮動小数点は深く理解しようとしたら大変なので(僕もまだちゃんとわかってない...)、とりあえず`double`型を入れておけばだいたいいけると思います。


#B問題 - [Circle](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/4/ITP1_4_B)

**問題**
半径 r の円の面積と円周の長さを求めるプログラムを作成して下さい。

面積と円周の長さを１つの空白で区切って１行に出力して下さい。出力は浮動小数点数とし、0.00001 以下の誤差を含んでもよいものとします。

**制約**
0 < r < 10,000

**数値例**
*input* : 2
*output* : 12.566371 12.566371

---
**解法**

円の面積は 半径 × 半径 × 円周率、円周の長さは 直径 × 円周率 なので、そのとおりに読み込んだ数値を入れていくだけです。
C#では円周率はMathクラスの `Math.PI` メソッドです。

今回も浮動小数点での出力と誤差は小数点第5位までに注意しましょう。

```ITP1_4_B.cs
using System;

class Program
{
    static void Main()
    {
        double r = double.Parse(Console.ReadLine());

        //円周率=Math.PI
        double a = r * r * Math.PI;
        double b = 2 * r * Math.PI;
        Console.WriteLine("{0} {1}", a.ToString("f5"), b.ToString("f5"));
    }
}

```


**コメント**
んー公式どおりなので特になし！


#C問題 - [Simple Calculator](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/4/ITP1_4_C)

**問題**
２つの整数 a, b と１つの演算子 op を読み込んで、a op b を計算するプログラムを作成して下さい。ただし、演算子 op は、"+"(和)、"-"(差)、"*"(積)、"/"(商)、のみとし、割り算で割り切れない場合は、小数点以下を切り捨てたものを計算結果とします。

**制約**

- 0 ≤ a, b ≤ 20000
- 0 による割り算が与えられることはありません。

**数値例**
*input*
1 + 2
56 - 18
13 * 2
100 / 10
27 + 81
0 ? 0

*output*
3
38
26
10
108

---
**解法**
読み込んだ通りに処理して出力するだけです。
「割り算で割り切れない場合は、小数点以下を切り捨てたものを計算結果とします。」とありますが、int型で計算すれば勝手に切り捨ててくれるので特に処理は必要ないです。

```ITP1_4_C.cs
using System;

class Program
{
    static void Main()
    {
        while(true)
        {
            string[] inputs = Console.ReadLine().Split(' ');
            int a = int.Parse(inputs[0]);
            int b = int.Parse(inputs[2]);
            string s = inputs[1];

            if (s == "+") Console.WriteLine(a + b);
            else if (s == "-") Console.WriteLine(a - b);
            else if (s == "*") Console.WriteLine(a * b);
            else if (s == "/") Console.WriteLine(a / b);
            else break;
        }
    }
}
```


**コメント**
特にnothing of nothing

#D問題 - [Min, Max and Sum](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/4/ITP1_4_D)

**問題**
n 個の整数 a(i)(i=1,2,...n)を入力し、それらの最小値、最大値、合計値を求めるプログラムを作成してください。

**制約**

- 0 < n ≤ 10000
- −1000000 ≤ a(i) ≤ 1000000

**数値例**
*input*
5
10 1 5 4 17

*output*
1 17 37

---
**解法**

配列/リストを作って、LINQにある配列処理のメソッドを使って処理します。

最大値、最小値、合計値の計算は以下のメソッドです。

- 最大値 : `配列/リスト.Max()`
- 最小値 : `配列/リスト.Min()`
- 合計値 : `配列/リスト.Sum()`

なお平均は、 `配列/リスト.Average()`です。

```ITP1_4_D.cs
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        int n = int.Parse(Console.ReadLine());
        List<long> inputs = Console.ReadLine().Split(' ').Select(t => long.Parse(t)).ToList();
        Console.WriteLine("{0} {1} {2}", inputs.Min(), inputs.Max(), inputs.Sum());
    }
}
```

**コメント**
longを使ってるのはintだと桁が溢れてしまうからです。


#さいごに
浮動小数点型はぶっちゃけ僕も完全に理解してるわけじゃないんですけど、float/double/decimalで試してたらどれかは通る場合が多いです。なので最初はとりあえず慣れることを重視したらいいと思ってます。

配列の最大値/最小値/合計値/平均値はちょくちょく使うのでしっかり覚えておくといいと思います。所感ですが、合計値が一番使う気がします。

では今日はこのへんで！