LoginSignup
0
0

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

Posted at

目次

A - Scoreboard

問題

解説

文字列 S を1文字ずつASCIIコードへ変換し、大文字と小文字の判定を行います。

ASCIIコードが91以上なら小文字、91未満なら大文字になります。
ASCIIコードへの変換はichar関数を用います。

プログラム例

program abc338a
    !S:文字列
    implicit none
    character(100) S
    integer i

    !入力
    read (*, *) S

    !1文字目が大文字かどうか
    if (ichar(S(1:1)) > 90) then
        write (*, '(a)') 'No'
        stop
    end if

    !2〜100文字目が小文字かどうか
    do i = 2, len_trim(S)
        if (ichar(S(i:i)) < 91) then
            write (*, '(a)') 'No'
            stop
        end if
    end do
    write (*, '(a)') 'Yes'
end program abc338a

B - Frequency

問題

解説

文字列 S を1文字ずつASCIIコードへ変換し、変数char_cntに出現回数を記録します。

最頻出の回数の取り出しは、maxval関数変数char_cntに対して行うことで求めます。
再頻出回数は変数char_maxに格納します。

結果の出力は、変数char_cntを1から順に調べ、変数char_maxと値が一致するアルファベットを出力します。
変数char_cntを1から順に調べることで、再頻出のアルファベットが複数個ある場合にも、辞書順の若い順番の答えとして出力が可能です。

プログラム例

program abc338b
    !S       :文字列
    !char_num:変換後のASCIIコード
    !char_cnt:各アルファベットの出現回数を記録
    !char_max:再頻出の文字の出現回数
    implicit none
    character(1000) S
    integer i, char_num, char_cnt(127), char_max

    !入力
    read (*, *) S

    !各アルファベットの出現回数を記録
    char_cnt = 0
    do i = 1, len_trim(S)
        char_num = ichar(S(i:i))
        char_cnt(char_num) = char_cnt(char_num) + 1
    end do

    !再頻出の文字の出力
    char_max = maxval(char_cnt)
    do i = 1, 127
        if (char_max == char_cnt(i)) then
            write (*, '(a)') char(i)
            stop
        end if
    end do
end program abc338b

C - Leftover Recipes

問題

解説

$1≤N≤10$であるため、料理Aと料理Bの作成数の組み合わせを2重のfor文総当たりするとTLEになります。
料理Aの作成数を先に決めておき、その後に余った材料数から料理Bの作成できる最大個数を求めることで、計算量を削減できます。

初期の材料在庫を変数Q(i)、料理Aに必要な材料数を変数A(i)、料理Aの作成個数を変数x、とする時、余った材料数変数Qr(i)は、Qr(i)=Q(i)-x ×A(i)で求められます。

料理Bに必要な材料数を変数B(i)とした時、料理Bの作成個数変数yは、y=Qr(i)/B(i)により求められます。

プログラム例

program abc338c
    !x     :料理Aの作成個数
    !y     :材料B(i)のみ作成できる料理Bの数
    !min_y : 料理Bの作成個数
    !max_xy:料理ABの最大個数
    !Q     :初期の材料在庫
    !A,B   :料理A,Bを作成するのに必要な材料個数
    !Qr    :料理A作成後に余ったの材料在庫
    implicit none
    integer i, j, x, y, min_y, max_xy
    integer N
    integer, allocatable::Q(:), A(:), B(:), Qr(:)

    !入力
    read (*, *) N
    allocate (Q(N), A(N), B(N), Qr(N))
    read (*, *) (Q(i), i=1, N)
    read (*, *) (A(i), i=1, N)
    read (*, *) (B(i), i=1, N)

    !料理作成数の組み合わせ検証
    min_y = 1000000000
    max_xy = 0; x = 0
    L1: do
        L2: do i = 1, N
            Qr(i) = Q(i) - A(i)*x
            if (Qr(i) < 0) exit L1
            if (B(i) == 0) cycle
            y = Qr(i)/B(i)
            min_y = min(y, min_y)
        end do L2
        max_xy = max(max_xy, min_y + x)
        x = x + 1
    end do L1

    !結果の出力
    write (*, *) max_xy
end program abc338c
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