int型
概要
最も代表的な整数型。
使わない問題はほぼない。
int 型は $32$ ビットの整数型(AtCoder環境の場合)。
符号用の $1$ ビットと、値の大きさ用の $31$ ビットを使う。
そのため、扱える値の範囲は $-2{,}147{,}483{,}648$ から $2{,}147{,}483{,}647$ まで。
およそ $\pm 20$ 億、$\pm 2 \times 10^9$ くらいまでは大丈夫で、それを超えると危ないと認識するとよい。
宣言と初期化
宣言だけする場合
int a;
初期化もする場合
int a = 0; // 固定値で初期化
int b = a; // 他の整数型や double 型の変数で初期化
可能な演算
代入 =
a=b; で、変数 a の中身を b に書き換える。
数学とは違い、左右を逆にして b=a; と書くと意味が変わるので注意。
加算 +
a+b で、a と b の和を計算する。
片方が long long 型だと結果も long long 型に、片方が double 型だと結果も double 型になる。
減算 -
a-b で、a と b の差を計算する。
片方が long long 型だと結果も long long 型に、片方が double 型だと結果も double 型になる。
乗算 *
a*b で、a と b の積を計算する。
片方が long long 型だと結果も long long 型に、片方が double 型だと結果も double 型になる。
除算 /
a/b で、a を b で割ったときの商を計算する。
整数型同士の割り算は、商と余りを出す方式の割り算で行われる。
正の数同士なら、小数部分を切り捨てたと考えてもよい。
負数の場合は、後述する注意点を参照。
b が $0$ の場合はエラーするので注意。
片方が long long 型だと結果も long long 型になる。
片方が double 型だと、小数部分まで商を求め、結果も double 型になる。
剰余 %
a%b で、a を b で割ったときの余りを計算する。
整数型同士の割り算は、商と余りを出す方式の割り算で行われる。
負数の場合は、後述する注意点を参照。
b が $0$ の場合はエラーするので注意。
片方が long long 型だと結果も long long 型になる。
片方が double 型だとエラーになる。
AND &(B問題相当)
詳しくは「ビット演算」の記事参照。
OR |(B問題相当)
詳しくは「ビット演算」の記事参照。
XOR ^(B問題相当)
詳しくは「ビット演算」の記事参照。
NOT ~(B問題相当)
詳しくは「ビット演算」の記事参照。
左シフト <<(B問題相当)
詳しくは「ビット演算」の記事参照。
右シフト >>(B問題相当)
詳しくは「ビット演算」の記事参照。
各種複合代入演算子
int 型では、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、および ++、-- が使える。
よく使う処理
以下の除算や倍数化の式では、$a \geq 0$、$b > 0$ で、計算時にオーバーフローしない範囲とする。
除算(切り上げ)
a/b を小数部分切り上げで計算したい場合、以下のようにすればよい。
(a+b-1)/b
余りが $1$ 以上なら、b-1 を足すことで商が $1$ 大きくなるという原理。
除算(四捨五入)
a/b を四捨五入で計算したい場合、以下のようにすればよい。
(2*a+b)/(2*b)
(2*a)/(2*b) と考えて、余りが b 以上あれば、b を足すことで商が $1$ 大きくなるという原理。
倍数判定
if文の条件に「a が b の倍数であるなら」を書きたい場合、以下のようにする。
if (a%b==0)
b の倍数であることと、b で割った余りが 0 であることは同じである。
「a が b の倍数でないなら」の場合は、以下。
if (a%b!=0)
特に、「a が偶数であるなら」は、以下。
if (a%2==0)
「a が奇数であるなら」は、以下。
if (a%2)
後者は、int 型の 0 以外の数が true として扱われる仕様を利用している。
自信がなければ、次のように明示的に書いてもよい。
if (a%2!=0)
倍数化
a に近い b の倍数を探す場合、b で割ってから b を掛ければよい。
小さい方へ探すなら切り捨てを利用して、以下。
a/b*b
大きい方へ探すなら切り上げを利用して、以下。
(a+b-1)/b*b
どちらでもよいから近い方へ探すなら四捨五入を利用して、以下。
(2*a+b)/(2*b)*b
これで、a に最も近い b の倍数を求めることができる。
負数の場合は、後述する注意点を参照。
特定の桁だけ抽出
非負整数 n の、例えば百の位を取り出したい場合、以下のようにする。
(n/100)%10
100 で割ることで右に $2$ 桁ずらしてから、10 で割った余りを求める。
10 で繰り返し割りながらforループを実行することで、全ての桁をばらばらに取り出すこともできる。
全ての桁を1つずつ抽出
上で書いた、全ての桁をばらばらに取り出す方法。
以下は n の値が壊れるので、必要なら n を別の変数にコピーし、そちらを利用して実行すること。
while (n>0) {
int m = n%10;
n /= 10;
// 取り出した m についての処理
}
char 型化(B問題相当)
0 以上 9 以下の整数を、char 型に変換する。
ASCIIコード上で '0' から '9' までが連続で並んでいることを利用できる。
数 a に対して、その数字の char 型データを得たい場合、以下の結果を char 型変数に入れる。
a+'0'
逆に、数字を表す char 型の文字 c を実際の数にしたい場合、以下のようにする。
c-'0'
文字列化(B問題相当)
int 型の数 a を string 型に変換したい場合、以下のようにする。
to_string(a)
逆に、string 型の文字列 s を int 型にしたい場合、以下のようにする。
stoi(s)
ただし、変換後の値が int 型に収まるかどうかを確認すること。
注意点
桁あふれに注意
int 型が扱える範囲は、およそ $\pm 20$ 億が限界。
絶対値 $10$ 億以下の数 $2$ つの足し算なら収まるが、$3$ つ足すと範囲を超える場合がある。
絶対値 $4$ 万以下の数 $2$ つの掛け算なら収まるが、$3$ つ掛けると範囲を超える場合がある。
桁あふれしそうな場合には、long long 型を使うこと。
負数の除算の商と余りに注意
数学的には、$-7$ を $3$ で割った商を $-3$、余りを $2$ とすることがある。
しかし、C++の整数除算では商が $0$ の方向へ丸められるため、商は $-2$、余りは $-1$ と計算される。
割る数が正で、余りを $0$ 以上にしたい場合は、普通に商と余りを求めた後に追加処理を行う。
具体的には、余りが負なら、商から $1$ を引き、余りに割る数を加える必要がある。
ビット演算の優先順位に注意
ビット演算系は、計算の優先順位がかなりややこしい。
省略せずに括弧を付けて優先順位を明示すると、バグが起きにくくなる。
関連アルゴリズム
long long型
int 型より大きな整数を扱う型。
int 型で桁あふれする場合に利用する。
double型
小数を扱う型。
int 型との演算では、結果が double 型になる。
char型
$1$ 文字を扱う型。
0 以上 9 以下の整数と数字を表す文字は、'0' を足し引きすることで相互変換できる。
string型
文字列を扱う型。
to_string で int 型から変換でき、stoi で int 型へ変換できる。
ビット演算
整数を二進数のビット列として扱い、AND、OR、XOR、NOT、シフトなどを行う。
最大公約数
$2$ つ、または $3$ つ以上の整数の最大公約数を得る方法と、その活用。
最小公倍数
$2$ つ、または $3$ つ以上の整数の最小公倍数を得る方法と、その活用。
bit全探索
$N$ 個のものをそれぞれ採用するかしないかで $2^N$ 通りを全探索したい場合に利用する。
N進法
十進法から $K$ 進法へ、または $K$ 進法から十進法へ変換する方法。