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

## A - N-choice question
問題は[こちら](https://atcoder.jp/contests/abc300/tasks/abc300_a)です。
回答は以下の通りです。

総当たりで選択肢を調べました。
A+Bをは比較の際に頻繁に使用するので、あらかじめ計算しておきました。
(変数ansに格納しています。)

```fortran
program ABC300a
    implicit none
    integer N, A, B, ans, i
    integer, allocatable :: C(:)
    !入力
    READ (*, *) N, A, B
    allocate (C(N))
    READ (*, *) C

    !一致するものがあるか検索
    ans = A + B
    do i = 1, N
        if (ans == C(i)) then
            write (*, "(i0)") i
            stop
        end if
    end do
end program
```

## B - Same Map in the RPG World
問題は[こちら](https://atcoder.jp/contests/abc300/tasks/abc300_b)です。
回答は以下の通りです。

全移動パターンを総当たりで調べています。
ただし、縦方向の移動は`H回以上の移動は調べる必要がありません。`
なぜなら、`H+n回の移動結果とn回の移動結果は`同じになるためです。(H回で１周するため)

同様に、横方向も`W回以上の移動は調べる必要がありません。`

```fortran
program ABC300b
    implicit none
    integer H, W, i, j, move_v, move_h
    character(3), allocatable :: A(:, :), B(:, :), ans_v(:, :), ans_h(:, :)
    !H,W の入力
    read (*, *) H, W
    allocate (A(H, W))
    allocate (B(H, W))
    allocate (ans_v(H, W))
    allocate (ans_h(H, W))

    !A,Bの入力
    do i = 1, H
        read (*, '(*(a1))') (A(i, j), j=1, W)
    end do
    do i = 1, H
        read (*, '(*(a1))') (B(i, j), j=1, W)
    end do

    !縦にmove_v移動
    do move_v = 0, H - 1
        !縦の移動を全マス反映
        do i = 1, H
            do j = 1, W
                if (i + move_v > H) then
                    ans_v(i, j) = A(i + move_v - H, j)
                else
                    ans_v(i, j) = A(i + move_v, j)
                end if
            end do
        end do
        !横にmove_h移動
        do move_h = 0, W - 1
            !横の移動を全マス反映
            do j = 1, W
                do i = 1, H
                    if (j + move_h > W) then
                        ans_h(i, j) = ans_v(i, j + move_h - W)
                    else
                        ans_h(i, j) = ans_v(i, j + move_h)
                    end if
                end do
            end do
            !結果確認用
            !write (*, *) 'v=', move_v, 'h=', move_h
            !do i = 1, H
            !   write (*, *) (ans_h(i, j), j=1, W)
            !end do
            !結果判定
            if (all(ans_h == B)) then
                write (*, "(a)") "Yes"
                stop
            end if
        end do
    end do
    write (*, "(a)") "No"
end program
```


## C - Cross
問題は[こちら](https://atcoder.jp/contests/abc300/tasks/abc300_c)です。
回答は以下の通りです。

総当たりで#を調べています。
#の発見後、周囲のマスを調べ、バツ印か成立しているかを調べます。
また、`バツ印の形は正方形なので、最大サイズはmin(H,W)になります。`

なお下記のプログラムだと、`k=1の場合にcnt(0)が現れ、存在しない範囲を指定することになります。`
本来であれば、if文を用いて回避するべきですが、判定文が１回増えて処理に時間がかかりそうなので入れませんでした。
結果としてACでしたので、このままにしています。

```fortran
program ABC300c
    implicit none
    integer H, W, i, j, k, size
    character(1), allocatable :: C(:, :)
    integer, allocatable::cnt(:)

    !H,W の入力
    read (*, *) H, W
    allocate (C(H, W))
    size = min(H, W)
    allocate (cnt(size))

    !Cの入力
    do i = 1, H
        read (*, '(*(a1))') (C(i, j), j=1, W)
    end do

    !#をカウント
    cnt = 0
    do i = 2, H - 1
        do j = 2, W - 1
            if (C(i, j) == '#') then
                do k = 1, size
                    if (C(i - k, j - k) == '#' .and. C(i - k, j + k) == '#' &
                        .and. C(i + k, j - k) == '#' .and. C(i + k, j + k) == '#') then
                        cnt(k) = cnt(k) + 1
                        cnt(k - 1) = cnt(k - 1) - 1
                    else
                        exit
                    end if
                end do
            end if
        end do
    end do

    !結果出力
    write (*, '(*(i0, 1x))') cnt
end

```

## その他：重要な発見
今回のコンテストは非常に非常に勉強になりました。
### ①区切りのない入力を分けて格納する方法
B問題では、区切りがない文字を１文字ずつ分け、配列に格納する必要がありました。
例えば、「ABCDE」と入力したものに対して、[A][B][C][D][E]と分けて配列に格納する必要があります。

コンテスト後に[MrTiredさんの回答](https://atcoder.jp/contests/abc300/submissions/41032305)を参考にさせていただきましたが、<font color="Red">read'(＊,＊(a1))')</font>で解決できる様です。(回答を見て感動しました、ありがとうございました。)

### ②出力する変数が未定の場合の指定方法
C問題では、回答としてバツ印の数を出力する必要があります。
ただし、H,Wが固定ではないため、出力する変数の数が一定ではありません。

コンテスト後に[MrTiredさんの回答](https://atcoder.jp/contests/abc300/submissions/41036303)を参考にさせていただきましたが、<font color="Red">write (＊, '(＊(i0, 1x))')</font>で解決できる様です。(回答を見て感動しました、ありがとうございました。)