Edited at

AOJをC#で解く②~ITP1_2~


はじめに

前回の記事はAOJのITP1_1について解説しました。

今回はAOJITP1_2の解説です。


ITP1_2

ITP1_2は条件分岐がテーマになっています。if文が出てくるかんじですね。


A問題 - Small, Large or Equal

問題

2つの整数 a, b を読み込んで、a と b の大小関係を出力するプログラムを作成して下さい。

制約

-1,000 ≤ a, b ≤ 1,000

数値例

1)

input : 1 2

output : a < b

2)

input : 4 3

output : a > b

3)

input : 5 5

output : a == b


解法

数値を読み込んで、if文で、


  • a < b

  • a > b

  • a == b

の3つに条件分岐するだけです。


ITP1_2_A.cs

using System;

namespace ITP1_2_A
{
class Program
{
static void Main(string[] args)
{
string[] s = Console.ReadLine().Split();
int a = int.Parse(s[0]);
int b = int.Parse(s[1]);

if (a < b)
{
Console.WriteLine("a < b");
}
else if (a > b)
{
Console.WriteLine("a > b");
}
else
{
Console.WriteLine("a == b");
}
}
}
}


コメント

if文は二つの分岐のときはifelseで、3つ以上の分岐の時は、ifelse ifで最後の分岐がelseとなります。あと最後のelseの時は()の条件指定は必要ないです。

なお、入力の部分のやり方は、string型の配列で読み込み、それをint型に変換するというやり方をとっています。けっこうよく使うので覚えておくといいです。


B問題 - Range

問題

3つの整数a, b, cを読み込み、それらが a < b < cの条件を満たすならば"Yes"を、満たさないならば"No"を出力するプログラムを作成して下さい。

制約

0 ≤ a, b, c ≤ 100

数値例

1)

input : 1 3 8

output : Yes

2)

input : 3 8 1

output : No


解法

a < b < c であることを判定すればよいので、if文の条件式をがa < b && b < cであればYes、そうでなければNoを返すプログラムにすればよいです。a < b < cと一気に書くことはできないので、ANDを表す論理演算子&&を使います。ちなみにORを表したい場合は||です。


ITP1_2_B.cs

using System;

namespace ITP1_2_B
{
class Program
{
static void Main(string[] args)
{
string[] x = Console.ReadLine().Split();
int a = int.Parse(x[0]);
int b = int.Parse(x[1]);
int c = int.Parse(x[2]);

if (a < b && b < c)
{
Console.WriteLine("Yes");
}

else
{
Console.WriteLine("No");
}
}
}
}


コメント

特にないですが、書いていて自分ですごく気になったのがなんでa < b < cという書き方はできないのかってことですね。ゴリゴリの機械学習エンジニアやってる友だちによると、この書き方をサポートしている言語もあって構文解析がめんどくさいからではないかということを言われました。slackでぱって聞いただけだったので、今度ちゃんと話聞いたり、いろいろ調べてまとめようと思います。


C問題 - Sorting Three Numbers

問題

3つの整数を読み込み、それらを値が小さい順に並べて出力するプログラムを作成して下さい。

制約

1 ≤ 3つの整数 ≤ 10,000

数値例

input : 3 8 1

output : 1 3 8


解法

いくつか解き方があります。最も基本的なのは、3つの数値の大小関係を把握して大きい順に並び替えて出力するというものです。B問題の要領で、



  • a < b && b < c:そのまま出力


  • a < b && b > ca < ca > cの場合で分けて出力。


  • a > b && b < ca < ca > cの場合で分けて出力。

という形式になると思います。

今回僕がやってるのはLINQというC#のライブラリを使っています。

int[] x = Console.ReadLine().Split().Select(int.Parse).ToArray();

これはConsole.ReadLine().Split()で読み込んだ文字列をSelect(int.Parse)でint型に変換し、ToArrayで配列に格納しています。

そしてここからがLINQのすごく便利なところなのですが、Sortメソッドを使えば、一発で昇順に並び替えてくれます。あとはそれを出力するだけです。


ITP1_2_C.cs

using System;

using System.Linq;

namespace ITP1_2_C
{
class Program
{
static void Main(string[] args)
{
int[] x = Console.ReadLine().Split().Select(int.Parse).ToArray();

Array.Sort(x);
Console.WriteLine(x[0] + " " + x[1] + " " + x[2]);
}
}
}


コメント

LINQについては僕もまだまだ学んでる途中なのですが、すごく便利なのでC#やる時は調べとくといいです!特に配列などの処理は便利なものが多いのです!!


D問題 - Circle in a Rectangle

問題

長方形の中に円が含まれるかを判定するプログラムを作成してください。次のように、長方形は左下の頂点を原点とし、右上の頂点の座標 (W,H) が与えられます。また、円はその中心の座標 (x,y) と半径 r で与えられます。

image.png

制約


  • 100≤x,y≤100

  • 0<W,H,r≤100

数値例

1)

input : 5 4 2 2 1

output : Yes

2)

input : 5 4 2 4 1

output : No


解法

だめなパターンは何か?を考えると解けます。

まずxとyがともに正の値を取る第一象限にある場合は、


  • x + r > W

  • y + r > H

となる時がだめなパターンです。

次に、xまたはyが負の値を取るときもだめなパターンです。

なのでこれのパターンをコードに落として、if文の条件文に入れたらおっけーです。その際、ANDじゃなくてORで記述することに気をつけて。


ITP1_2_D.cs

using System;

namespace ITP1_2_D
{
class Program
{
static void Main(string[] args)
{
string[] i = Console.ReadLine().Split(' ');

int W = int.Parse(i[0]);
int H = int.Parse(i[1]);

int x = int.Parse(i[2]);
int y = int.Parse(i[3]);
int r = int.Parse(i[4]);

if (x < 0 || y < 0 || x + r > W || y + r > H)
{
Console.WriteLine("No");
}
else
{
Console.WriteLine("Yes");
}
}
}
}


コメント

今回のようにダメなパターンをだして潰すというやり方はけっこう有効な場合が多いので、問題解決のメソッドとして身につけておくとよいと思います。競プロだけでなく他の多くの事象にも当てはまると思うので。


さいごに

読んでくれてありがとうございます。

説明の過不足や言葉の誤用あれば指摘オネガイシマス。(ないはずだが...)