ebisukeプログラミング初心者脱出黙示録

30歳を過ぎてから始めたプログラミングと競プロの記録。Pythonで取り組んでいます。Arduinoで電子工作も

AtCoder-ABC191 C - Digital Graffiti【Python解答例】

AtCoder Beginner Contest191は2完でしたが気を取り直してD問題まで復習していきます。
この記事ではC問題を記事にしていきます。
atcoder.jp


AtCoder Beginner Contest191 C - Digital Graffiti

C - Digital Graffiti

問題文

H 行 W 列のマス目があります。このマス目の、上から i 番目、左から j 番目のマスを、マス (i,j) と呼ぶことにします。
各マスは黒または白に塗られています。Si,j が # ならばマス (i,j) は黒に塗られており、. ならば白に塗られています。
マス目の一番外側のマス、すなわち (1,j),(H,j),(i,1),(i,W) のいずれかの形で表されるマスは白に塗られていることが保証されます。
黒に塗られた部分を多角形として見たとき、これが (最小で) 何角形になるかを求めてください。
ここで、黒に塗られた部分は一つの自己交叉のない多角形となることが保証されます。すなわち、以下のことが保証されます。

黒に塗られたマスが少なくとも一つ存在する
黒に塗られた任意の 2 マスは、辺を共有するマスへの移動を繰り返し、黒に塗られたマスのみを通って互いに到達可能である
白に塗られた任意の 2 マスは、辺を共有するマスへの移動を繰り返し、白に塗られたマスのみを通って互いに到達可能である(マス目の一番外側のマスは全て白に塗られていることに注意してください)

制約

・3≤H≤10
・3≤W≤10
・Si,j は # または .
・S1,j,SH,j は .
・Si,1,Si,W は .
・黒に塗られた部分は一つの自己交叉のない多角形となる

解答例

h, w = map(int,input().split())

A = []
for i in range(h):
    array = input()
    A.append(array)

ang = 0
for i in range(h):
    for j in range(w):
        temp = 0
        if A[i-1][j-1] == "#":
            temp += 1
        if A[i][j-1] == "#":
            temp += 1
        if A[i-1][j] == "#":
            temp += 1
        if A[i][j] == "#":
            temp += 1
        if temp == 1 or temp == 3:
            ang += 1
else:
    print(ang)

解説

白と黒に塗られたマス目があり、黒のマス目の角が何個あるか答える問題です。
公式解説を見てACできました。

マス目(i,j)の左上の角において、左上の角の周りのマス目(i-1 , j-1)(i , j-1)(i-1, j)(i , j)の黒色の数が1か3のとき、求める頂点になります。

したがって、(i,j)の左上の角の周りの黒色のマス目の数をtempで数えて、1か3なら答えとなるang変数に1を足しました。

最後にang変数を出力すればACでした。


コンテスト中はいろいろ考えましたが、この考え方は思いつきませんでした。
法則を見つける力が足りないですね。



D問題もあれこれ試しましたがコンテストでは解けませんでした。
復習がんばって そちらも記事にしていきたいです。

ABC191の関連記事はこちら
ebisuke33.hatenablog.com