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

## 目次
  - [A - Online Shopping](#a---online-shoppingw)
  - [B - Glass and Mug](#b---glass-and-mug)
  - [C - T-shirts ](#c---t-shirts )

## A - Online Shopping
### 問題

N 種類の商品が売られているお店で商品を購入します。

i 種類目の商品は 1 個 $P_i$ 円で、 $Q_i$ 個購入しました。
購入時は送料が発生し、商品の合計金額が S 円以上なら 0 円、そうでないならば K 円かかります。

送料を含めた支払い額を求めてください。

>**制約**
>1. $1≤N≤100$ 
>2. $1≤S≤10000$ 
>3. $1≤K≤10000$
>4. $1≤P_i≤10000$
>5. $1≤Q_i≤100$
>6. 入力はすべて整数

詳細はこちらです。

https://atcoder.jp/contests/abc332/tasks/abc332_a

### 解説
商品の合計金額を求め、金額によって送料の加算処理を行います。


### プログラム例
```Fortran
program abc332a
    !P(N) ：商品の値段
    !Q(N) ：商品の購入個数
    !S    ：送料の無料ライン
    !K    ：送料
    !price：支払い金額
    implicit none
    integer i
    integer N, S, K
    integer, allocatable:: P(:), Q(:)
    integer price

    !入力
    read (*, *) N, S, K
    allocate (P(N), Q(N))
    do i = 1, N
        read (*, *) P(i), Q(i)
    end do

    !購入金額の計算
    do i = 1, N
        price = price + P(i)*Q(i)
    end do

    !送料の計算
    if (price < S) price = price + K

    !結果の出力
    write (*, *) price
end program abc332a
```



## B - Glass and Mug
### 問題
容量が G ml のグラスと、容量が M ml のマグカップが 1 つずつあります。

グラスとマグカップはいずれも空です。
以下の操作を K 回繰り返した後で、グラスとマグカップに水がそれぞれ何 ml ずつ入っているか求めてください。

>**各操作**
>1. グラスが水で満たされているとき、すなわちグラスにちょうど G ml 入っているとき、グラスの水をすべて捨てる。
>2. マグカップが空であるとき、マグカップを水で満たす。
>3. マグカップが空になるかグラスが水で満たされるまで、マグカップからグラスに水を移す。

>**制約**
>1. $1≤K≤100$
>2. $1≤G<M≤1000$
>3. G,M,K は整数

詳細はこちらです。

https://atcoder.jp/contests/abc332/tasks/abc332_b

### 解説
指定の操作回数 K 回を満たすまで、前項で示した操作を行います。


### プログラム例
```Fortran
program abc332b
    !G        ：グラスの容量
    !M        ：マグカップの容量
    !current_G：現在グラスに入っている水の量
    !current_M：現在マグカップ入っている水の量
    !K        ：繰り返し回数
    !cnt      ：現在の繰り返し回数
    implicit none
    integer G, M
    integer current_G, current_M
    integer K
    integer cnt
    !入力
    read (*, *) K, G, M
    current_G = 0; current_M = 0; cnt = 0

    !水の移し替え
    do
        !グラスが満杯なら水を捨てる
        if (current_G == G) then
            current_G = 0
            cnt = cnt + 1
            if (cnt >= K) exit
        end if

        ! マグカップが空なら水を入れる
        if (current_M == 0) then
            current_M = M
            cnt = cnt + 1
            if (cnt >= K) exit
        end if

        !マグカップからグラスに水を移す
        select case (current_G)
        case (0) !グラスが空
            if (current_M > G) then !マグカップの残量がグラスの残量より多い
                current_M = current_M - G
                current_G = G
            else !マグカップの残量がグラスの残量より少ない
                current_G = current_M
                current_M = 0
            end if
        case (1:) !グラスが空でない
            if (current_M > G) then !マグカップの残量がグラスの残量より多い
                current_M = current_M - (G - current_G)
                current_G = G
            else !マグカップの残量がグラスの残量より少ない
                current_M = 0
                current_G = current_G + current_M
            end if
        end select
        cnt = cnt + 1
        if (cnt >= K) exit
    end do
    write (*, '(i0,1x,i0)') current_G, current_M
end program abc332b
```



## C - T-shirts 
### 問題
A さんの N 日間の予定が 0, 1, 2 のみからなる長さ N の文字列 S で与えられます。
0, 1, 2 では以下の予定を消化します。

>**予定**
>０　何の予定も入っていません。
>１　食事に行く予定があります。
>２　競技プログラミングのイベントに行く予定が入っています。

予定を消化する際には、「無地の T シャツ」、「AtCoder のロゴ入りの T シャツ」を着る予定です。具体的に述べると、以下の方針に従ってシャツを着ていきます。

>1. 食事に行く日には、無地の T シャツ 1 枚またはロゴ入りの T シャツ 1 枚を着用する
>2. 競技プログラミングのイベントに行く日にはロゴ入りの T シャツ 1 枚を着用する。
>3. 何の予定もない日には T シャツを着用しない。加えてその時点で着用済みの T シャツを全て洗濯する。 洗濯したT シャツは翌日から着用できる。
>5. 一度着用した T シャツは次に洗濯するまで着用できない。

1 日目の時点で洗濯済みの無地の T シャツを M 枚持っている場合、予定を全て消化しきる場合にはロゴ入りの T シャツは何枚いるかを求めてください。

>**制約**
>1. $1≤M≤N≤1000$
>2. S は 0, 1, 2 のみからなる長さ N の文字列
>3. N,M は整数

詳細はこちらです。

https://atcoder.jp/contests/abc332/tasks/abc332_c


### 解説
予定0 が来れば着ることのできる T シャツの枚数リセットされます。 
「予定0 で囲まれた範囲」で必要となる Tシャツの枚数の最大数を求めることで、購入すべきシャツの枚数を知ることができます。



### プログラム例
```Fortran
program abc332c
    !N    ：予定の日数
    !M    ：無地のTシャツの所有枚数
    !S    ：各予定の内容
    !tmp_M：必要な無地Tシャツの枚数(暫定)
    !tmp_T：必要なロゴTシャツの枚数(暫定)
    !max_T：必要なロゴTシャツの最大数
    implicit none
    integer i
    integer N, M
    character(:), allocatable ::S
    integer tmp_M, tmp_T, max_T

    !入力
    read (*, *) N, M
    allocate (character(N)::S)
    read (*, *) S
    max_T = 0; tmp_T = 0; tmp_M = 0

    !Tシャツの集計
    do i = 1, N
        select case (S(i:i))
        case ("0") !予定なし(洗濯)
            call wash_shirt(tmp_T, tmp_M, max_T, M)
            tmp_T = 0; tmp_M = 0; 
        case ("1") !食事の予定
            tmp_M = tmp_M + 1
        case ("2") !プログラミングのイベント
            tmp_T = tmp_T + 1
        end select
    end do
    call wash_shirt(tmp_T, tmp_M, max_T, M)

    !結果の出力
    write (*, *) max_T
contains
    subroutine wash_shirt(tmp_T, tmp_M, max_T, M)
        !tmp_M：0で囲まれた区間で必要な無地Tシャツの枚数(暫定)
        !tmp_T：0で囲まれた区間で必要なロゴTシャツの枚数(暫定)
        !max_T：必要なロゴTシャツの最大数
        !cnt_T：0で囲まれた区間で必要な無地Tシャツの枚数(確定)
        !cnt_M：0で囲まれた区間で必要な無地Tシャツの枚数(確定)
        !M    ：無地のTシャツの所有枚数
        integer tmp_M, tmp_T, max_T, M
        integer cnt_T, cnt_M
        cnt_T = 0; cnt_M = 0

        !無地Tの集計
        if (tmp_M > M) then !無地Tの所持数より必要数が多い
            cnt_T = tmp_M - M
            cnt_M = 0
        else !無地Tの所持数より必要数が少ない
            cnt_M = M - tmp_M
            cnt_T = 0
        end if

        !ロゴTの集計
        cnt_T = cnt_T + tmp_T

        !最大値の更新
        if (max_T < cnt_T) max_T = cnt_T
    end subroutine wash_shirt
end program abc332c
```