背景
- AtCoder Beginner Contest 297に参加しました。
- 自身のプログラミング技術の向上と、Fortranの発展を願って投稿します。
(Fortran使ってる人が6000人中2人でした。かなしい。) - A問題とC問題はこちら。(記事が長くなるので分けました。)
実行環境
- Macbook(M1)
- Docker
- VsCode
- Fortran(gcc version 10.2.1)
問題内容
問題文はこちらです。
いろいろ書いてありますが、内容は次のとおりです。
長さ8文字
の文字列Sには、K,Qがちょうど1文字
、R.B,Nがちょうど2文字
含まれています。
Sの中身を調べて、以下の条件がどちらも満たしているか
判定します。
1. 2つのBの位置が左から数えて
偶数•奇数
もしくは奇数•偶数
の位置にあるか。
(例えば、1文字目、2文字目や4文字目、5文字目なら良い)
2. Kの文字がRの文字に挟まれているかどうか。
(例えばRKR○○○○○やR○○○○K○Rなら良い)
条件を満たしていれば、YES
と出力します。満たしていなければ、No
と出力します。
解説ポイント
基本的な考え方は、公式の解説(C++)の通りとなります。
以下はFortranでのポイントと注意点です。
-
K,Q,R,B,Nは
必ず
指定した文字数含まれています。Kが1文字もないケース等は考える必要はありません。 -
文字型の状態で1つずつ比較するのは大変です。
従って、文字ごとに出現位置(左から何文字目か)を数字で管理する
と楽です。 -
偶数と奇数の判定は
mod
で処理した余りから判定します。 -
YesとNoは
左詰め
で出力します。従って、書式を指定する必要があります。
サンプルコード
program ABC297b
implicit none
integer(8) i, j, k, K1
integer(8) B2(2), R2(2)
character(8):: S
j = 1
k = 1
!write (*, *) '>> S'
read (*, *) S
do i = 1, 8
if (S(i:i) == 'B') then
B2(j) = mod(i, 2)
j = j + 1
else if (S(i:i) == 'K') then
K1 = i
end if
if (S(i:i) == 'R') then
R2(k) = i
k = k + 1
end if
end do
!print *, 'R=', R2; print *, 'B=', B2; print *, 'K=', K
if (R2(1) < K1 .and. K1 < R2(2) .and. B2(1) .ne. B2(2)) then
write (*, "(a)") 'Yes'
else
write (*, "(a)") 'No'
end if
end program