#はじめに
前回の記事はAOJのITP1_1について解説しました。
#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
input : 4 3
output : a > b
input : 5 5
output : a == b
解法
数値を読み込んで、if文で、
- a < b
- a > b
- a == b
の3つに条件分岐するだけです。
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文は二つの分岐のときはif
とelse
で、3つ以上の分岐の時は、if
とelse 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
input : 3 8 1
output : No
解法
a < b < c であることを判定すればよいので、if文の条件式をがa < b && b < c
であればYes、そうでなければNoを返すプログラムにすればよいです。a < b < c
と一気に書くことはできないので、ANDを表す論理演算子&&
を使います。ちなみにORを表したい場合は||
です。
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 > c
:a < c
とa > c
の場合で分けて出力。 -
a > b && b < c
:a < c
とa > c
の場合で分けて出力。
という形式になると思います。
今回僕がやってるのはLINQというC#のライブラリを使っています。
int[] x = Console.ReadLine().Split().Select(int.Parse).ToArray();
これはConsole.ReadLine().Split()
で読み込んだ文字列をSelect(int.Parse)
でint型に変換し、ToArray
で配列に格納しています。
そしてここからがLINQのすごく便利なところなのですが、Sortメソッドを使えば、一発で昇順に並び替えてくれます。あとはそれを出力するだけです。
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 で与えられます。
制約
- 100≤x,y≤100
- 0<W,H,r≤100
数値例
1)
input : 5 4 2 2 1
output : Yes
input : 5 4 2 4 1
output : No
解法
だめなパターンは何か?を考えると解けます。
まずxとyがともに正の値を取る第一象限にある場合は、
- x + r > W
- y + r > H
となる時がだめなパターンです。
次に、xまたはyが負の値を取るときもだめなパターンです。
なのでこれのパターンをコードに落として、if文の条件文に入れたらおっけーです。その際、ANDじゃなくてORで記述することに気をつけて。
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");
}
}
}
}
コメント
今回のようにダメなパターンをだして潰すというやり方はけっこう有効な場合が多いので、問題解決のメソッドとして身につけておくとよいと思います。競プロだけでなく他の多くの事象にも当てはまると思うので。
#さいごに
読んでくれてありがとうございます。
説明の過不足や言葉の誤用あれば指摘オネガイシマス。(ないはずだが...)