このテキストは、ICPCラボというサークルに入ってくれた新入部員の方々に向けて競技プログラミングについてざっくり書いたものです。わかりづらい部分などはちょこちょこ修正していきます。
うちのサークルでは競技プログラミングの大会、ICPCへの出場に向けてこつこつと勉強をしています。近々飲み会とかもしたいね!
目次
- 競技プログラミングの流れ
- Javaの書き方
- 必要とされる知識
- 勉強方法
競技プログラミングの流れ
基本的には、こんな流れとなります。
- 問題を読む
- コードを書く
- 提出する
なんとなくイメージをするため、簡単な例を見てみましょう。
以下のような表記で、九九を出力して終了するプログラムを作成して下さい。(×記号の代わりに、小文字の x を使用すること)
1x1=1
1x2=2
.
.
9x8=72
9x9=81
これに対する答えは、たとえばこのようになります。
```java
public class Main {
public static void main(String[] args) {
int k = 0;
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
k = i * j;
System.out.println(i + "x" + j + "=" + k);
}
}
}
}
こういったコードを書いたら、手元で実行して出力を確認し、提出します。
書いたコードを実行する際、Javaではコンパイルという作業が必要になります。といっても簡単で、まずWindowsならコマンドプロンプト、Macならターミナルを開きます。
そして、たとえばHello, Worldを出力するプログラムファイルをデスクトップ上に置いているとすると以下のように実行できます。
$ cd desktop
desktop$ javac Main.java
desktop$ java Main
Hello, World
Javaの書き方
Javaは初心者にとっては書くことが多いので、すべて理解できなくても焦ることはありません。困ったことがあった時に「知らんわそんなもん」と開き直れるくらいの図太さが(最初のうちは)必要です。
「こんにちは」を出力
public class Main {
public static void main(String[] args){
System.out.println(“こんにちは”);
}
}
「どうしてこんにちはを出力をしたいだけなのに、こんなに書かなくてはいけないの?」と考えだすとつらくなります。
System.out.println
がテキストを出力するための呪文で、その中身として「こんにちは」を渡していると捉えればOKです。またその上下の何やらごちゃごちゃ書かれているものについては、「この決まり文句で挟んであげないと、目的の処理をしてくれないのね」という理解で十分です。先にも書きましたが、図太く考えましょう。
入力をオウム返し
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner s = new Scanner(System.in);
String a = s.next();
System.out.pritnln(a);
}
}
先ほどと同じ決まり文句の中に、Scannerだのなんだの出てきました。またしても決まり文句として覚えましょう。とはいっても、意味だけは理解するためにこの部分を日本語で書くきます。こんなかんじです。
入力をもらう
はじめの入力をaにいれる
そのaを出力する
日本語だと簡単ですね。さて、1行目のimportというのはなんでしょう。これはScannerというクラス(いろんな機能がごちゃごちゃ入った道具箱のようなもの)を使うために書いています。要するにこのimport java.util.Scanner
という1行は、「Scanner使わせてくれ」という意味です。
必要とされる知識
競技プログラミングを楽しむために、何が必要なのか。これはおそらく、大きく分けると2つです。
言語(Java)の知識
競技プログラミングという、ある意味特殊な目的のためにプログラミングをするので、必ずしも言語について習熟する必要はないのかもしれません。けれど、本番である特定の関数名がわからないために時間を浪費してしまうのは避けたいです。リファレンス無しである程度やりたい処理をささっと書けるようになるべきだと思います。
アルゴリズム
アルゴリズムとは、問題に対する解法の総称で、もっと狭く捉えるとプログラミングにおけるレシピのようなものです。先に挙げた九九の計算だとfor文を2つ重ねることで九九に必要な乗算の繰り返しを実装していますが、こういう簡単なものでもアルゴリズムといえると思います。
アルゴリズムの勉強は、僕のように数学を避けて英語・現代文・日本史で大学受験したような文系野郎にはけっこう厳しいものです。しかし、競技プログラミングをやってみると、これは避けて通れません。
勉強方法
ひたすら解く
これがなかなか難しいのですが、結局は問題を解くしか無いのかなあと。一時期、本を読んで理解してから問題を解こうとしたこともあったのですが、あまりうまく行きませんでした。学んだはずの事柄が、次の日にはさっぱり頭から消えているのです。
そうなるよりかは、実際に問題を解いて、分からない点を整理して、1つずつ潰していくしかないと思います。気をつけないといけないのは、わからないことがわかるようになるまでしっかり時間を費やさないと本番で使えるレベルにはならないということです。「なんとなくわかった」は全くなにもしてないのとあまり変わりません。
具体的には、AOJ, Paiza, CodeIQなどで問題を解きます。今はオンラインでプログラミング問題を提供してくれているサイトがたくさんあります。これらを使っていきましょう。
コードを読む
AOJには、他の回答者のコードを読むことができます。なので、それらを読んで「これってどういう意味?」と突き詰めていくと、かなり良い勉強になりそうです。言語の勉強として、自分が書いたコードを読み返して「そういえばpublic class Main
のpublicって何なの?」と調べてみるのも楽しそうです。
説明する
理解したら、仲間に説明できるようになるといいですね。説明をするのは口頭でもいいし、できればブログやQiitaなどに文章として残せるのが理想です。あたりまえだけど、文章にして残しておくと後で読み返したりできるので、便利です。