競技プログラミング用 知識集積所
if分岐
最終更新:
sport_programming
-
view
雑な説明
変数の中身次第で特定のコードを実行したりしなかったりする。
あるいは、複数のコードのどれを実行するか選ぶ。
あるいは、複数のコードのどれを実行するか選ぶ。
レベル
ABCのA問題以降。
基本的な記述
コードを実行したりしなかったりする
if (条件式) { その場合に実行したいコード }
実行したいコードが1行しかない場合は
if (条件式) その場合に実行したいコード
でもよい。
2つのコードのどちらを実行するか選ぶ
if (条件式) { その場合に実行したいコード } else { そうじゃない場合に実行したいコード }
実行したいコードが1行しかない場合は
if (条件式) その場合に実行したいコード else そうじゃない場合に実行したいコード
でもよい。
3つ以上のコードのどれを実行するか選ぶ
if (条件1) { 条件1を満たす場合に実行したいコード } else if (条件2) { 条件1を満たさないが条件2を満たす場合に実行したいコード } else { 条件1も条件2も満たさない場合に実行したいコード }
else if のところを増やしていけば、4択や5択、それ以上も可能。
実行したいコードが1行しかない場合については同様。
実行したいコードが1行しかない場合については同様。
条件式に使える基本的な記述
等しい a==b
整数型の場合は、数値が等しければtrue。
double型の場合は、数値が等しければtrue……だが、あまり信用ならない(詳細はdouble型の注意点参照)
char型の場合は、同じ文字であればtrue。
string型の場合は、完全に同じ文字列であればtrue。
pair※、tuple※、vectorの場合は、個数と順番まで含め完全に同じ内容であればtrue。
set※の場合は、完全に同じ内容であればtrue。
double型の場合は、数値が等しければtrue……だが、あまり信用ならない(詳細はdouble型の注意点参照)
char型の場合は、同じ文字であればtrue。
string型の場合は、完全に同じ文字列であればtrue。
pair※、tuple※、vectorの場合は、個数と順番まで含め完全に同じ内容であればtrue。
set※の場合は、完全に同じ内容であればtrue。
等しくない a!=b
==がfalseになるならtrue。
より小さい a<b
整数型の場合は、数値がaの方が小さければtrue。
double型の場合は、数値がaの方が小さければtrue……だが、あまり信用ならない場合がある(詳細はdouble型の注意点参照)
char型の場合は、aの方がASCIIコードが小さければtrue。
string型の場合は、前から順に見て最初に異なる文字のところを探し、そこのASCIIコードがaの方が小さければ、またはaの方だけもう文字が尽きていればtrue。
pair※、tuple※、vectorの場合も前から順に見て最初に内容の異なるところを探し、そこがaの方が小さければ、またはaの方だけもう内容が尽きていればtrue。
double型の場合は、数値がaの方が小さければtrue……だが、あまり信用ならない場合がある(詳細はdouble型の注意点参照)
char型の場合は、aの方がASCIIコードが小さければtrue。
string型の場合は、前から順に見て最初に異なる文字のところを探し、そこのASCIIコードがaの方が小さければ、またはaの方だけもう文字が尽きていればtrue。
pair※、tuple※、vectorの場合も前から順に見て最初に内容の異なるところを探し、そこがaの方が小さければ、またはaの方だけもう内容が尽きていればtrue。
以下 a<=b
a<bかa==bが成り立てばtrue。
より大きい a>b
b<aが成り立てばtrue。
以上 a>=b
a>bかa==bが成り立てばtrue。
発展的な記述
aとbの間の数という判定
真面目に書くと、
if ((a<x&&x<b)||(b<x&&x<a))
とすることになり、やや煩雑。
実はこれ、
if ((x-a)*(x-b)<0)
と書ける。
ただし桁あふれに注意。
ただし桁あふれに注意。
あるいは、
if (min(a,b)<x&&x<max(a,b))
とも書ける。
そうじゃなければ、という条件(B問題レベル)
if (!条件) { そうじゃない場合に実行したいコード }
if (!q.empty())
と書くような場合に必要になる。
2つの条件をどちらもチェックしたい場合
2つの条件が両方成り立つなら実行、という場合は
if (条件1&&条件2)
2つの条件が片方だけでも成り立つなら実行、という場合は
if (条件1||条件2)
と書く。詳細はbool型参照。
3つや4つでも、個数が定まっているなら同様に書ける。
3つや4つでも、個数が定まっているなら同様に書ける。
また、このとき、条件1の結果によっては、条件2がチェックされない。
つまり、
つまり、
if (条件1&&条件2)
において条件1がfalseだった場合、条件2は確認せずに全体をfalseとして処理する。
これを利用すると、条件2での範囲外アクセスのエラーを防ぐことができる。
これを利用すると、条件2での範囲外アクセスのエラーを防ぐことができる。
例えば、aというベクトルに対し、
if (a.size()>10&&a.at(10)>0)
と書くことで「10番目が正の数ならtrue、正の数でないかそもそも存在しなければfalse」と書ける。
(例えばaの長さが5であった場合、1つめの条件でfalseになるため2つめの判定が行われず、範囲外アクセスが発生しない)
(例えばaの長さが5であった場合、1つめの条件でfalseになるため2つめの判定が行われず、範囲外アクセスが発生しない)
同様に、
if (条件1||条件2)
において条件1がtrueだった場合、条件2は確認せずに全体をtrueとして処理する。
これもやはり条件2での範囲外アクセスのエラーを防ぐことができる。
これもやはり条件2での範囲外アクセスのエラーを防ぐことができる。
多数(不定個)の条件を全てチェックしたい場合
注意点
等しいと書くつもりで誤って=と書かないこと。
もし
if (x=0)
と書いた場合、意図と違う挙動をする。
これは、条件部分にbool型以外の値が入っていた場合でもそれぞれtrue扱いやfalse扱いにすると定めてあるため。
バグの発見が非常にしにくいので注意。
謎のWAが出た場合はとりあえずif文の中身を一通り確認してみる、くらいに警戒が必要。
これは、条件部分にbool型以外の値が入っていた場合でもそれぞれtrue扱いやfalse扱いにすると定めてあるため。
バグの発見が非常にしにくいので注意。
謎のWAが出た場合はとりあえずif文の中身を一通り確認してみる、くらいに警戒が必要。
類似アルゴリズム
whileループ
if分岐と似ているが、条件に合う限り何度でも繰り返して実行する。