【超初心者向け】競技プログラミングの事始め【C++】
はじめに
プログラミング初心者で、競技プログラミングを始めてみたい人
C++ について勉強したい人
この記事では、プログラミング初心者の方に向けてやさしく解説しています。
競技プログラミングとは
問題が出題されて、それに回答するプログラムを書く競技です。
オンラインでも開催されており、回答した問題の点数や回答までの時間などによって順位がつきます。
日本では AtCoder が有名で、定期的にコンテストが開催されています。コンテストに参加して問題を解けば Rating がつくので、ゲーム感覚で取り組むこともでき、アルゴリズムの勉強のモチベーション維持にも役立ちます。
例えば、AtCoder で開催された「ABC086」コンテストでは、次のような問題が出題されました。
これに回答するプログラムを書いて、いろいろな入力に対して、正確な出力ができるかを判定して、すべての入力に対して正しければ正解になります。
AtCoder では、定期的にコンテストが開催(土曜や日曜の21時からが多い)されているので、コンテストへ参加しやすく、コンテストの成績によってレートが変化します。
競技プログラミングを始めるのに AtCoder はオススメです。
AtCoderに登録する
AtCoder に登録してみましょう。AtCoder は無料で利用できます。
新規登録ページにアクセスして登録します。
※ユーザ名の変更は、一度しかできないので注意してください。
初めての問題を解いてみる
AtCoder で練習用の問題を解いてみましょう。
ちなみに、この問題を解いてもレートの変動はありません。予定されたコンテストについて、「Rated参加登録」で参加したときのみレートが変わります。
問題では、何個かの入力例と出力例が例示されています。
問題では、a + b + c を表示し、そのあとに空白で s を表示させる必要があります。
入力例では、 a が1、 b が2、 c が3なので、a + b + c = 1 + 2 + 3 = 6 になります。s は test なので出力する答えは、「6 test」になります。
コードを提出する
問題ページを下の方にスクロールすると、ソースコードと書かれたところがあります。
ここにコードを書きます。プログラミング言語は、Java や Python など様々なプログラミング言語で提出することができます。
次は C++ で書いたコードです。言語が「C++(GCC 9.2.1)」になっていることを確認して、このコードをソースコードの欄に貼り付けてください。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 整数の入力
int a, b, c;
cin >> a >> b >> c;
// 文字列の入力
string s;
cin >> s;
// 出力
cout << (a + b + c) << " " << s << endl;
return 0;
}
貼り付けたら、「提出」をクリックしてください。
ページが変わって、結果が確認できます。結果が AC (Accepted)になっていれば問題に正解できたということです。WJ (Waiting for Judging)は、
採点中なので、少し待っていれば結果が表示されます。
結果は AC 以外に次のようなものがあります。
CE(Compiulation Error):コンパイルに失敗
MLE(Memory Limit Exceeded):メモリ制限越え
TLE(Time Limit Exceeded):実行時間制限越え
RE(Runtime Error):スタックオーバーフロー、ゼロ除算などのエラー
OLE(Output Limit Exceeded):出力サイズ制限越え
IE(Internal Error):ジャッジシステムのエラー
WA(Wrong Answer):出力が正しくない
C++についての説明
AtCoderでは、いろいろなプログラミング言語でコードを提出することができます。
自分の得意なプログラミング言語があればそれでいいですが、ないのなら C++ がおすすめです。
C++ は実行速度が他の言語に比べて高速で、多くの解説記事や競技プログラミングの本で C++ のコードで解説されているからです。
C++ のプログラムは、1つ以上の関数でできています。基本的には、次ようなコードです。
実際のコードだと、次のようなものです。
int main() {
return 0;
}
戻り値の型:int
関数名:main
仮引数リスト:なし
戻り値:return 0
プログラムの処理のひとまとまりを関数と言います。ここでは、main という関数です。C++ では、main() 関数はプログラムの実行開始点になります。
main() 関数が、きちんと終了したことを表すのに 0 を返します。
0 は整数なので、戻り値の型は、符号付き整数を表す int になります。
戻り値の型 関数名(仮引数リスト){
処理;
}
int main() {
return 0;
}
例えば、Aさんに段ボールの在庫を数えてもらうとします。
「Aさん、段ボールの在庫を数えてくれる。終わったら、在庫があるか、ないかを教えてくれるかな。」
簡単に言えばAさんが関数のことで、Aさんがする処理が、段ボールの数を数えることです。そして、戻り値が「あるか、ないか」です。
「Aさん、段ボールの在庫を数えてくれる。終わったら、段ボールの在庫の数を教えてくれるかな。」
この場合、戻り値は「段ボールの在庫の数」になります。
コードの中の、// で始まる行はコメント行と言われ、プログラムの実行には関係しません。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 整数の入力 ← ここはコメント行
int a, b, c;
cin >> a >> b >> c;
// 文字列の入力 ← ここはコメント行
string s;
cin >> s;
// 出力 ← ここはコメント行
cout << (a + b + c) << " " << s << endl;
return 0;
}
標準ライブラリと名前空間
C++ では、コードを簡単に書くために便利な機能が用意されています。そのいろいろな機能をまとめたものが標準ライブラリ(STL:Standard Template Library)です。
標準ライブラリを使うためには『#include <bits/stdc++.h>』が必要になります。
これをコードの最初に書いておくことで、入力に使う「cin」や出力に使う「cout」のコマンドが使えるようになります。
標準ライブラリは複数のファイルに分かれていますが、『#include <bits/stdc++.h>』を使うことですべての標準ライブラリの機能が使えるようになります。
cin や cout の入出力関連の機能を使うだけなら『#include <bits/stdc++.h>』ではなく『include <iostream>』を書くだけでも動きます。
練習用の問題は、以下のコードでも正解になります。
#include <iostream> // ここを #include <bits/stdc++.h> から変更している
using namespace std;
int main() {
// 整数の入力
int a, b, c;
cin >> a >> b >> c;
// 文字列の入力
string s;
cin >> s;
// 出力
cout << (a + b + c) << " " << s << endl;
return 0;
}
標準ライブラリの機能を使うためには、その機能の前に std:: を書く必要があります。
標準ライブラリの cout を使うときは、次のようなコードになります。
次のコードを実行すれば Hello, World と出力されます。
#include<bits/stdc++.h>
int main () {
std::cout << "Hello, World" << std::endl; //STLの機能を使うために「std::」が必要
return 0;
}
Atcoder のコンテストでは、解くまでの時間も重要になります。そのため、できるだけコードのタイピングの量を減らすことも大事になります。
std:: を書かないようにするのが、『using namespace std;』です。これをプログラムに書いておくことで、std:: を省略することができます。
次のコードも、先ほどと同じように Hello, World と出力します。
『using namespace std;』を書くことで std:: を省略ことができました。
#include<bits/stdc++.h>
using namespace std;
int main () {
cout << "Hello, World" << endl; //「std::」を省略できる
return 0;
}
次のコードが、基本的なテンプレートです。
#include <bits/stdc++.h>
using namespace std;
int main() {
// ここに問題に解答するための処理を書いていく
return 0;
}
解答コードの説明
問題は次のようなものでした。
その問題に正解するコードです。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 整数の入力
int a, b, c;
cin >> a >> b >> c;
// 文字列の入力
string s;
cin >> s;
// 出力
cout << (a + b + c) << " " << s << endl;
return 0;
}
問題に解答するためには、与えられる整数と文字列を受けとる必要があります。
入力
C++ では、cin を使えば入力を受けとることができます。次のように使います。
入力は1つずつ受けとる必要はなく、 cin >> 変数 >> 変数 >> 変数; のように書くこともできます。
C++ では、文の終わりには「;」を書く必要があるので注意してください。
実際のコードでは、次のように使われています。
cin >> a >> b >> c;
cin >> s;
a, b, c, s という名前の変数に入力を受けとっています。変数というのは名前のついた箱のようなものです。
変数
C++ で変数を使うときには、あらかじめ変数を宣言しておく必要があります。変数を宣言するときは、変数の型をコンピュータに伝えるという意味もあります。
一般的には次のように変数を宣言します。
実際のコードでは、次のように変数を宣言しています。
int a, b, c;
string s;
int は符号付き整数を表し、string は文字列を表します。符号付き整数の a, b, c と、文字列の s という名前の変数を宣言しています。
ちなみに、変数の型が同じときは「,」で区切ってまとめて変数を宣言することができます。int a, b, c; と次のコードは同じです。
int a;
int b;
int c;
算術式
変数に入力を受けとることができました。問題は、a + b + c の計算結果を出力する必要があります。
C++ では、次のような算術演算子があります。
+ : 足し算
ー : 引き算
* : 掛け算
/ : 割り算
% : 割った余り
普段の計算式と同じような感じで使うことができます。
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << 1 + 4; // => 5
cout << 4 - 3; // => 1
cout << 3 * 2; // => 6
cout << 6 / 3; // => 2
cout << 7 % 2; // => 1 7 ÷ 2 = 3 余り 1
cout << 1 + 2 * 4; // => 9
cout << (1 + 2) * 4; // => 12
return 0;
}
「*」、「/」、「%」は「+」、「ー」よりも先に計算されます。
計算順序を変えるときは、括弧を使います。
出力
出力するには cout を使います。
改行するには endl を使います。
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "Hello,";
cout << "World";
// => Hello,World
cout << "Hello," << endl;
cout << "World";
// => Hello,
// => World
return 0;
}
解答コードをもう一度見てみます。
整数と文字列を入力として受け取り、整数は計算し、出力しています。
#include <bits/stdc++.h>
using namespace std;
int main() {
// 整数の入力
int a, b, c;
cin >> a >> b >> c;
// 文字列の入力
string s;
cin >> s;
// 出力
cout << (a + b + c) << " " << s << endl;
return 0;
}
まとめ
アルゴリズムやプログラミングの勉強には AtCoder がおすすめです。解ければレートがあがり、リアルタイムで順位を競うのでゲーム感覚で行うことができます。
始めれば、負けたくない、レートを上げたいと思うのが人間です。
レートを上げるために勉強を始めるはずです。どんどんコンテストに出場しましょう。
プログラミングの経験はあるけど、C++ は初めてという方に向けての記事も書いています。
過去問を解くのがおすすめです。素晴らしいサイトがあります。AtCoder の過去問をレベル別に並び替えたりすることができます。
書籍では、アルゴリズムなどの知識を体系的に学ぶことができるのでお勧めです。
この記事が気に入ったらサポートをしてみませんか?