章末問題
以下の問題を用意しておきました。解いてプログラミングになれましょ。
例題 1
与えられた数が素数かどうか判定する関数を実装せよ。
bool is_prime(long n) {
// ここに書く
return true;
}
解き方
愚直に 2 から n 未満までのどの数でも割り切れないかどうか調べるとこうなる。
bool is_prime(long n) {
for (long i = 2; i < n; ++i) {
if (n % i == 0) {
return false;
}
}
return true;
}
でも、√n 以下の数までで割れるかどうか調べるだけでいい。
bool is_prime(long n) {
for (long i = 2; i * i <= n; ++i) {
if (n % i == 0) {
return false;
}
}
return true;
}
実際はもうちょっと効率の良いやり方もあるけれど、大抵はこのくらいで大丈夫。
問 1
こんな入力がされる。
N M
V1
V2
V3
:
VN
Q1
Q2
Q3
:
QM
NはVの個数を表す整数。MはQの個数を表す整数。Vは整数。Qは0以上N未満の整数。
それぞれの Q ごとに、Q 番目 (0 始まり) の V が偶数なら 1 を、奇数なら 0 を出力せよ。
入力例:
5 8
3
1
7
8
-2
2
2
3
0
4
1
1
2
出力例:
00101000
問 2
V 個の異空間どうしが、E 個のポータルで繋がれている。0 番目の空間から、V - 1 番目の空間へ移動したい。でもポータルをたくさん通ってしまうと何らかの負荷が大きいので、ポータルを通る回数をできるだけ少なくしたい。
最小で何回通ればいいか計算しよう。
E V
src1 dst1
src2 dst2
:
srcE dstE
Eはsrcとdstの個数を表す整数Vは正の整数srcとdstは0以上V未満の整数0番目の空間からV - 1番目の空間まで到達できないような入力はない。
各ポータルは src 番目の空間から dst 番目の空間につながっている。
ポータルを通る最小の回数を出力せよ。
入力例:
5 5
0 1
1 2
1 4
4 3
3 5
出力例
4
クリックでヒントを見れるよ
幅優先探索をしながら、「その空間に到達できる最小の通った回数」をメモするようにしてみよう。
問 3
なんか知らんけど迷路に迷い込んでいるみたい。だが都合のいいことに迷路の地図がある。お小水も近いので早く脱出したい。
現在地からゴールまでの最短経路を求めよう。
W H
Ix Iy
maze_1_1 maze_1_2 .. maze_1_W
maze_2_1 maze_2_2 .. maze_2_W
: : :
maze_H_1 maze_H_2 .. maze_H_W
WとHは0以上2e3以下の整数Ixは0以上W未満の整数Iyは0以上H未満の整数mazeは文字で、'#'か' 'のどちらか- 最短経路が二通り以上ある / 存在しないような入力はない。
W は迷路の幅で、H は迷路の高さ。
左上を (x, y) = (0, 0) として、現在位置は (Ix, Iy) である。
ゴールは外周の空いたマスならどこでもいい。
通る道を '.' にして出力せよ。
入力例:
10 10
1 1
##########
# ## # #
# # # # #
# # # #
# # # ## #
# # # #
# # # ##
# # # # ##
# # # #
######## #
出力例:
##########
#.## #...#
#.# #.#.#
#.#....#.#
#.#.# ##.#
#...# #..#
# # #.##
# # # #.##
# # #..#
########.#
クリックでヒントを見れるよ
探索している座標を (x, y) とすると、
x == 0 || y == 0 || x == W - 1 || y == H - 1 のときに探索が終了する。
幅優先探索をしながら、「そのマスに最短で到達できるときの通ってきた方向」をするといいかも。