キーエンスプログラミングコンテスト2022(ABC274) A～D問題 ものすごく丁寧でわかりやすい解説 python 灰色～茶色コーダー向け #AtCoder

キーエンスプログラミングコンテスト2022(AtCoder Beginner Contest 274) A～D問題の解説記事です。
灰色～茶色コーダーの方向けに解説しています。

その他のABC解説、動画などは以下です。

https://qiita.com/sano192/items/54accd04df62242b70f0

更新時はツイッターにて通知します。
https://twitter.com/AtCoder4

# キーエンス様について
採用情報

https://www.keyence-jobs.jp/

https://job.axol.jp/pm/c/keyence/public/top

# A Dif:23

https://atcoder.jp/contests/abc274/tasks/abc274_a

単純にB/Aを四捨五入して3桁目までを出力すればいい・・・だけなのですが四捨五入の処理は意外と難しいです。
こういうときはあまり考え込まずにさっさと「python 四捨五入」で検索しましょう。
やりかたはいくつかありますが、公式解説の通りfを使うのが楽です。

f"{(数字):.(小数点以下の桁数)f}"
というように指定します。「:」以下がオプション、「.」が少数の意味で、後ろに桁数というイメージです。

入力の受け取り、出力がわからない方は以下の記事を参考にしてください。

https://qiita.com/sano192/items/6361ed72106cb6dd5843#1-%E5%85%A5%E5%8A%9B%E3%81%A8%E5%87%BA%E5%8A%9B-abc205-a-dif6

**【提出】**

```python:
# 入力の受け取り
A,B=map(int, input().split())

# (B/A)を少数第4位を四捨五入して3桁まで出力
print(f"{B/A:.3f}")
```

# B Dif:48

https://atcoder.jp/contests/abc274/tasks/abc274_b

入力を二次元配列として受け取り、各列ごとに「#」の数を確認します。
まずマス目を記録するGridという空のリストを用意します。
Grid=[]
各行ごとに入力を文字列で受け取ります。C="#..#"であるとしましょう
C="#..#"
list(文字列)とすることで1文字ずつリストへ格納することができます。
list(C)=["#" , "." , "." , "#"]
更にそれをGridに格納していくことで二次元配列が出来上がります。
Grid=[["#" , "." , "." , "#"]]
これを全ての行について行うことで全ての要素をGridへ記録できます。例えばこんな感じです。
Grid=[["#" , "." , "." , "#"],["#" , "#" , "." , "#"],["." , "." , "." , "#"]]
Grid[行番号][列番号]とすることで(行番号,列番号)の要素を確認する事ができます。(ただし番号は0から始まることに注意してください)

後はfor文で列ごとに「#」を数えるだけです。

**【提出】**

```python:
# 入力の受け取り
H,W=map(int,input().split())

# 要素を記録するリスト
Grid=[]

# H回
for i in range(H):
    # 文字列として受け取り
    C=input()
    # 1文字ずつリストへ展開
    C=list(C)
    # 記録
    Grid.append(C)

# 答えの記録
ans=[]

# w=0~(W-1)
for w in range(W):
    # 「#」の個数
    count=0

    # h=0~(H-1)
    for h in range(H):
        # Grid[h][w]=「#」ならば
        if Grid[h][w]=="#":
            # カウント
            count+=1

    # 答えの記録
    ans.append(count)

# 答えの出力(「*」をつけると[]なしで出力できる)
print(*ans)
```
# C Dif:315

https://atcoder.jp/contests/abc274/tasks/abc274_c

0代目(アメーバ1)から生まれたアメーバは1代目(1代親を遡るとアメーバ1になる)
1代目から生まれたアメーバは2代目
2代目から生まれたアメーバは3代目
...
となるので、アメーバが生まれた瞬間に(親アメーバの代数+1)を代数として記録していけばいいということがわかります。
すなわちアメーバ2i,(2i+1)は(Aiの代数+1)を記録していけばいいということです。

Aをそのまま受け取ると0インデックス、すなわちA1=A[0],A2=A[1],...となり、ややこしいので入力の受け取りのとき、先頭に0などてきとうな値でA[0]を埋めてしまうと楽です。

**【提出】**

```python:
# 入力の受け取り
N=int(input())
# 先頭をてきとうな数字(=0)で埋める
A=[0]+list(map(int,input().split()))

# 答え
ans=[0]*(2*N+2)

# i=1~N
for i in range(1,N+1):
    # (親の代+1)を記録する
    ans[2*i]=ans[A[i]]+1
    ans[2*i+1]=ans[A[i]]+1

# i=1~(2N+1)
for i in range(1,2*N+2):
    # 答えの出力
    print(ans[i])
```

# D Dif:916

https://atcoder.jp/contests/abc274/tasks/abc274_d

x座標の動きだけを考えてみましょう。
以下を例にします。
A：6 10 4 1 4 9 8 6 5 1

p1の時点ではx座標は0です。
p2の時点でx座標がA1=6になります。
p3はy座標方向への移動なのでx座標は変わりません。
p4のx座標は+A3か-A3になります。もともと6にいたので6+4=10,6-4=2のどちらかになります。
p5はy座標方向への移動なのでx座標は変わりません。
p6は+A5か-A5になります。もともと10または2にいたので10+4=14,10-4=6,2+4=6,2-4=-2のどれかになります。ここで6が被っているので実質的には14,6,-2のどれかになります。
...
これを繰り返すことでx座標の到達点としてあり得るものを計算することができます。

このやりかたは一見到達箇所の数が2,4,8,16,...とどんどんふえていく気がします。Nは最大1000なので最終的に2^500個到達箇所ができそうです。
しかしAiの最大値が10であることから、どれだけ進んでもx座標は-5000~5000くらいの範囲に収まります。
よって重複を記録しないようにすれば、一回あたりの計算量は大した量にはなりません。

実装は以下のように行います。
(1)x座標の到達先をセット(Sx)に記録する。初期値はA1のみ。
(2)i=3,5,7,...について、Sxの要素に順に＋A[i],-A[i]したものを新しいセット(NewSx)に記録する。
(3)Sx=NewSxと更新する。
y座標についても同様です。

記録したSx,Syにx,yが含まれていれば「Yes」、そうでなければ「No」を出力します。

**【提出】**

```python:
# 入力の受け取り
N,x,y=map(int,input().split())
# 先頭A[0]を適当な数字(=0)で埋めておく
A=[0]+list(map(int,input().split()))

# 到達可能なx座標のセット
Sx=set()
# 到達可能なy座標のセット
Sy=set()

# p2の時点でx座標はA1
Sx.add(A[1])
# y座標は0
Sy.add(0)

# i=2~N
for i in range(2,N+1):
    # 偶数番目(y座標方向への移動)
    if i%2==0:
        # 新しい到達先のy座標
        NewSy=set()

        # yi：Syの要素を順に代入
        for yi in Sy:
            # 新しい到達先を記録
            NewSy.add(yi-A[i])
            NewSy.add(yi+A[i])

        # Syを更新
        Sy=NewSy

    # 奇数番目(x座標方向への移動)
    else:
        # 新しい到達先のx座標
        NewSx=set()

        # xi：Sxの要素を順に代入
        for xi in Sx:
            # 新しい到達先を記録
            NewSx.add(xi-A[i])
            NewSx.add(xi+A[i])
        
        # Sxを更新
        Sx=NewSx

# xがSxにある かつ yがSyにある
if x in Sx and y in Sy:
    # 「Yes」を出力
    print("Yes")
# そうでなければ
else:
    # 「No」を出力
    print("No")
```

# 【広告】
## 『AtCoder 最速で緑になる 基礎・典型50問詳細解説』

ABC201～250から基礎・典型問題50問を**とてつもなく丁寧かつ詳細に**解説した本(kindle)、pdf(booth)です。
灰色、茶色コーダーにおすすめ！
値段：**100円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/dp/B0BBB7RKTP

**【booth(pdf)】**
https://booth.pm/ja/items/4102300

**冒頭5問をサンプルとして無料公開しています**
https://qiita.com/sano192/items/6361ed72106cb6dd5843

## 『AtCoder　凡人が『緑』になるための精選50問詳細解説』

AtCoderで緑になるための典型50問を**ひくほど丁寧に**解説した本(kindle)、pdf(booth)を販売しています。
値段：**100円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/gp/product/B09C3TPQYV/

**【booth(pdf)】**
https://sano192.booth.pm/items/3179185

**1～24問目まではサンプルとして無料公開しています**
https://qiita.com/sano192/items/eb2c9cbee6ec4dc79aaf

## 『AtCoder ABC201～225 ARC119～128 灰・茶・緑問題 超詳細解説 AtCoder 詳細解説』

**ABC201~225、ARC119~128** の **灰・茶・緑DIfficulty問題(Dif：0～1199)** を解説しています。
とにかく **細かく、丁寧に、具体例を豊富に、実装をわかりやすく、コードにコメントをたくさん入れて** 解説しています。

**サンプルを5問分公開しています**
https://qiita.com/sano192/items/3258c39988187759f756

Qiitaにて無料公開している『ものすごく丁寧でわかりやすい解説』シリーズをベースにしていますが、 **【キーワード】【どう考える？】【別解】を追加** し、 **【解説】と【実装のコツ】を分ける** ことでよりわかりやすく、 **具体例や図もより豊富に** 書き直しました。
Qiitaには公開していない **ARC119~128の灰・茶・緑DIfficulty問題も書き下ろし** ています。

値段：**300円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/dp/B09TVK3SLV

**【booth(pdf)】**
https://booth.pm/ja/items/3698647

**ARC119~128の部分のみ抜粋した廉価版** もあります。
値段：**200円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/dp/B09TVKGH17/

**【booth(pdf)】**
https://sano192.booth.pm/items/3698668

## 『AtCoder ABC226～250 ARC129～139 灰・茶・緑問題 超詳細解説 AtCoder 詳細解説』

**ABC226~250、ARC129~139** の **灰・茶・緑DIfficulty問題(Dif：0～1199)** を解説しています。
とにかく **細かく、丁寧に、具体例を豊富に、実装をわかりやすく、コードにコメントをたくさん入れて** 解説しています。

**サンプルを4問分公開しています**
https://qiita.com/sano192/items/f8f09ea769f2414a5733

Qiitaにて無料公開している『ものすごく丁寧でわかりやすい解説』シリーズをベースにしていますが、 **【キーワード】【どう考える？】【別解】を追加** し、 **【解説】と【実装のコツ】を分ける** ことでよりわかりやすく、 **具体例や図もより豊富に** 書き直しました。
Qiitaには公開していない **ARC129~139の灰・茶・緑DIfficulty問題も書き下ろし** ています。

値段：**300円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/dp/B0B7G13QMS

**【booth(pdf)】**
https://sano192.booth.pm/items/4025713

**ARC129～139の部分のみ抜粋した廉価版** もあります。
値段：**200円(Kindle Unlimited対象)**
**【kindle】**
https://www.amazon.co.jp/dp/B0B7G337YF

**【booth(pdf)】**
https://sano192.booth.pm/items/4025737

## 『Excelでリバーシを作ろう!!　マクロ、VBAを1から学ぶ』

Excelのマクロ(VBA)で「三目並べ」「マインスイーパー」「リバーシ」を作る解説本です！
マクロ、VBAが全くわからない人でも大丈夫！　丁寧な解説と図でしっかり理解しながら楽しくプログラミングを学ぶ事ができます！
**値段：300円(Kindle Unlimited対象)**

<iframe width="560" height="315" src="https://www.youtube.com/embed/J_uaNYRuuZU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

サンプルとして「準備」～「三目並べ」を無料公開しています。
https://qiita.com/sano192/items/9a47e6d73373d01e31fb

**【kindle】**
https://www.amazon.co.jp/dp/B09XLM42MW

**【booth(pdf】**
https://sano192.booth.pm/items/3785312