LoginSignup
0
0

More than 1 year has passed since last update.

【ABC299】FortranでA,B,C問題

Last updated at Posted at 2023-04-28

A - Treasure Chest

問題はこちらです。

回答は以下の通りです。
文字列Sを左から順番に調べて、|*|が成立している時点で処理を止めています。
doが入れ子になり過ぎていて、解き方としては美しくない気がします。

program ABC299a
    implicit none
    character(:), allocatable :: S
    integer N, i, j, k
    !データ読み込み
    READ (*, *) N
    allocate (character(N) :: S)
    READ (*, *) S
    !|*| の検索
    do i = 1, N - 1, 1
        if (S(i:i) == "|") then ! 検索:始点地点 "|"
            do J = I + 1, N, 1
                if (S(J:J) == "*") then ! 検索:中間地点 "*"
                    do K = J + 1, N, 1
                        if (S(K:K) == "|") then ! 検索:終点地点 "|"
                            !ここまで来たら成立しているので"in"にして終了
                            write (*, "(a)") 'in'
                            stop
                        end if
                    end do
                end if
            end do
        end if
    end do
    write (*, "(a)") "out" !doループを抜けている=”|*|”がないのでout
end program

B - Trick Taking

問題はこちらです。
回答は以下の通りです。

2段階に分けてプログラムを書きました。
初めに、色がTであるカードが存在するかについて、全カードを順番に調べました。
その次に、色Tカードの有無によって検索の条件を変え、最大値を全カード順番に調べました。

iからNまで調べる処理を2回しているので処理に時間かかりますが、今回は大丈夫でした。
(問題が複雑になるとこの方法は通じなくなると思います。)

program ABC299b
    !変数定義
    implicit none
    integer, allocatable :: C(:), R(:)
    integer N, T, i, Check2
    integer MaxNumber, MaxUser

    !入力
    READ (*, *) N, T
    allocate (C(N))
    allocate (R(N))
    READ (*, *) C
    READ (*, *) R

    !2があるか検索
    Check2 = 0
    MaxNumber = 0
    MaxUser = 0
    do i = 1, N
        if (C(i) == T) then
            Check2 = 1
            exit
        end if
    end do

    !最大値検索
    if (Check2 == 1) then ! 2がある場合
        do i = 1, N
            if (C(i) == T .and. R(i) > MaxNumber) then
                MaxNumber = R(i)
                MaxUser = i
            end if
        end do
    else ! 2がない場合
        do i = 1, N
            if (C(i) == C(1) .and. R(i) > MaxNumber) then
                MaxNumber = R(i)
                MaxUser = i
            end if
        end do
    end if

    !結果出力
    write (*, "(i0)") MaxUser
end program

C - Dango

問題はこちらです。
回答は以下の通りです。

問題文を見ると、-とoの両方について、前進方向と行進方向で調べる必要がありそうですが、
実際にはどちらか一方向に調べるだけで済みます。

なぜなら、前進と後進のどちらで最大値を検出したのかを報告する必要がないからです。
-が1文字でも含まれていれば、oと-は必ず接しているからです。
ただし、例外として全てoの場合の処理を考える必要があります。

(なお、今回の場合はダンゴ文字列の判定をoを開始判定、-を終了判定に使用しています。
そのため、1文字目が-で、2〜N文字目がoの文字列の判定が行えません。(例えば、N=3,S='-ooo')
なぜなら、N文字目に終了判定である-が来ないためです。
ダンゴ文字列は終了処理のためのの処理を考える必要があります。

プログラムとしてスッキリまとまっていて、個人的満足度が高いです。(うれしい)

program ABC299c
    implicit none
    character(:), allocatable :: S
    integer N, i, cnt, ans
    READ (*, *) N
    allocate (character(N) :: S)
    READ (*, *) S
    ans = 0
    cnt = 0
    do i = 1, N
        if (S(i:i) == "o") then
            cnt = cnt + 1
        else
            if (cnt > ans) ans = cnt
            cnt = 0
        END IF
        if (CNT > ans .AND. S(1:1) == '-') ans = cnt
    end do
    !結果出力
    if (ans .ne. 0) then
        write (*, "(i0)") ans
    else
        write (*, "(i0)") - 1
    end if

end program

余談

今回もDDoS攻撃を受け、Unratedになっていました。(かなしい)

また、Fortranで提出している方は3人でした。(+1人)
どちらの方もレベルが高く、提出コードを見て勉強させていただきました。
ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0