はじめに
最近、AtCoderでC++を使い始めましたC++初心者です。A問題の過去問を全て解き終わったところです。
最低限これだけを知っていれば、A問題は解けるという知識や関数をまとめました。これからAtCoderをC++で始めたいけど、始め方がわからないという方の少しでも役に立てばいいなぁと思います。
基本操作
配列
配列とは、値などを一纏めにしたものです。違う型のものを同じ配列に入れることはできません。
型 配列名[]という形で宣言します。
呼び出す時は配列名[i]という形で呼び出すことができます。iには数字が入ります。int型の変数も入れることができます。iのことをインデックスと言います。
#include <bits/stdc++.h>
using namespace std;
int main() {
// string型のweeksという配列を用意
string weeks[] = {"SUN","MON","TUE","WED","THU","FRI","SAT"};
cout << weeks[0] << endl;
=> SUN
cout << weeks[6] << endl;
=> STA
}
vector
配列と似ているものでvectorというものがあります。配列との違いは、vectorは必要に応じて大きさが自動的に変化します。配列よりもvectorの方が色々な関数を使うときにやりやすいので、基本的にはvectorを使うと思います。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 変数の宣言
int a, b, c;
// 入力の受付
cin >> a >> b >> c;
// 名前がvのvectorの宣言,入力で受け付けたa,b,cを格納しています
vector<int> v{a,b,c};
// 要素の指定は配列の時と同じです
cout << v[0] << endl;
}
vectorを利用した重複要素の削除
AtCoderでは、配列の重複する要素を削除する操作を必要とする場面に多く遭遇しますので、必須です。しかし、C++で重複する要素を削除する操作は少し複雑なので、ここで説明します。
また、よく使う関数もたくさん出ているので、一緒に覚えてしまいましょう。
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
vector<int> v{a,b,c};
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
cout << v.size() << endl;
}
sort関数
文字通り、配列を降順に並び替えます。何故、sortするかというと、uniqueを使うためです。あとで説明しましょう。
unique関数
“隣接する“重複要素を削除します。そう、隣接する要素だけです。例えば配列内が[1,2,1]になっていると、1が重複しているにも関わらず、1は削除してくれません。なので、その前にsortをかけて、順番を並び替えています。
また、要素を削除すると、?のゴミが残ります。[1,1,2] => [1,2,?]となり、配列の長さが変化しません。そこで、eraseを使います。
erase関数
指定した要素を削除します。この場合、uniqueを使ったことによって発生したゴミ(?)を削除しています。これによって、重複を削除した配列が得られました。
size関数
配列やベクター内の要素数を取得します。
if文
if (条件){
処理内容
}else if (条件){
処理内容
}else {
処理内容
}
if (条件){
処理内容
}
上記のような形になります。else ifやelseはいらない時は、なくても大丈夫です。下記に例を示しておきます。特に、条件によって、YESとNOを出力するパターンは嫌になるくらいよく使います。
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
if (b - c == c - b){
cout << "YES" << endl;
}else {
cout << "NO" << endl;
}
}
for文
// 構文
for(初期化式 ; 条件式 ; 増減式){
繰り返される箇所
}
for (int i = 0; i < 3; i++) {
cout << "YES" << endl;
}
上のコードでは”YES”を三回出力します。i=0でiを初期化して、i++により、ループが繰り返されるたびに、iに1を足していきます。そして、iが3より低い場合にループを繰り返します。
while文
// 構文
while (条件式){
実行される処理
}
int H = 10;
while(H < 0){
H = H - 1;
}
上のコードではループを繰り返すたびに、Hから1を引いていって、Hが0より小さくなったところで、ループが終わります。
for文とwhileの使い分けですが、何回繰り返すかわかっている時や配列を順番に処理したい時はfor文で、繰り返す回数がわからない時や入力された変数などをループの条件にしたい時はwhile文を使うのかなと思っています。
// for文を使うとき
// ABC 139: A – Tenki
int main() {
string S, T;
cin >> S >> T;
int count = 0;
// 長さが3の文字列S,Tが与えられ、3文字の中で同じ文字が幾つかるのかを数えて出力します
for (int i = 0; i < 3; i++) {
if (S[i] == T[i]){
count += 1;
}
}
cout << count << endl;
}
// while文を使う時
// ABC 153: A – Serval vs Monster
int main() {
int H, A;
cin >> H >> A;
int count = 0;
// HからAを引いて、Hが0より小さくなるなるまでの回数を出力します
while(H < 0){
H = H - A;
count += 1;
}
cout << count << endl;
}
数値操作
四則演算
#include <bits/stdc++.h>
using namespace std;
int main() {
int a = 4;
int b = 2;
// 加算
cout << a + b << endl;
=> 6
// 減算
cout << a - b << endl;
=> 2
// 乗算
cout << a * b << endl;
=> 8
// 除算
cout << a / b << endl;
=> 2
// 剰余
cout << a % b << endl;
=> 0
}
剰余は値が偶数か奇数かや倍数かどうかを判別する時によく使います。
#include <bits/stdc++.h>
using namespace std;
int main() {
int A;
cin >> A;
if(A % 2 == 0){
cout << "偶数です" << endl;
}else {
cout << "奇数です" << endl;
}
if(A % 3 == 0){
cout << "3の倍数です" << endl;
}else {
cout << "3の倍数ではありません" << endl;
}
}
累乗
pow関数
累乗を求める時にはpow関数を使います。pow(n, べき乗)という形で使います。
pow(n, 2) => nの二乗
pow(n, 3) => nの三乗
pow関数を使うためには、<math.h>をインクルードする必要がありますが、#include <bits/stdc++.h>と書いてあれば、含まれますので、追記する必要はありません。これは他の関数にも言えることです。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n = 4;
cout << pow(n, 2) << endl;
=> 16
// 平方根も求められます
cout << pow(n, 0.5) << endl;
=> 2
}
最大値、最小値
max関数、min関数
二つの値、もしくは配列内の最大値と最小値を表示します。
<algorithm>ヘッダをインクルードする必要があります。
int main() {
int a = 10;
int b = 11;
int c = 15;
int d = 20;
int e = 100;
cout << max(a,b) << endl;
=> 11
cout << max({c, d ,e}) << endl;
=> 100
}
max_element関数、min_element関数
ベクターに対して使います。ベクター内の最大値と最小値を表示します。
イテレータを返しますので、出力する時は頭に*を付けます。
int main() {
int a, b;
cin >> a >> b >> c;
vector<int> cal{a + b, b + c, c + a};
// 出力する際は、*を忘れずに
cout << *max_element(cal.begin(), cal.end()) << endl;
cout << *min_element(cal.begin(), cal.end()) << endl;
}
絶対値
abs関数
絶対値を返す関数です。値の差をとる時に使います。
整数の場合は、<cstdlib>ヘッダを、小数の場合は、<cmath>ヘッダをインクルードする必要があります。
下記のコードではxとの差が小さい方を出力しています。
int main() {
int X = 5;
int A = 2;
int X = 10;
if (abs(X - A) < abs(X - B)){
cout << "A" <<endl;
}else {
cout << "B" <<endl;
}
}
=> A
四捨五入
round関数
四捨五入をします。標準ライブラリ関数です。
例えば、小数点第2位で四捨五入をしたい時は下記のように書きます。
std::cout << std::round(3.154 * 100) / 100 << std::endl;
int main() {
float a, b;
cin >> a >> b;
int x = round((a + b) / 2);
cout << x <
文字列操作
カウント
count関数
count(変数名.begin(), 変数名.end(), ‘数えたい対象’)という形で使います。
ただし、変数の型はstring型でないと使えないので注意しましょう。問題で与えられるものが数値の場合でも、string型の変数に変換して格納しましょう。
int main() {
string a = "11223345"
cout << count(a.begin(), a.end(), '1');
=> 2
}
おわりに
こんなところでしょうか。A問題の過去問を42~156まで解いた感じ、ここに出てきたのを使うだけで、ほぼ解けると思います。
他の言語に比べて、C++はとてもとっつきにくいと思います。自分はrubyとpythonを勉強してきましたが、その二つに比べると、コードの記述がいちいちめんどくさいと感じてしまいます。
最初から、全てを覚えようとすると、大変なので、簡単な問題から解き始めて、徐々に覚えていくのがいいと思います。
B問題になるとまた難しくなるので、少しずつ覚えていきましょう。