[BOJ]#17144スモッグこんにちは!Python


質問する


https://www.acmicpc.net/problem/17144
スモッグを取り除くため、古いアップルは空気清浄機を設置する準備をしている.空気清浄機の性能をテストするために、古いりんごの家の大きさはRです.×C字で表示、1×1つの大きさの格子に分ける.旧アップルは優れた符号化能力を利用して,各格子(r,c)中のスモッグ量をリアルタイムで監視するシステムを開発した.(r,c)は、r行c列を表す.

空気清浄機は常に第1列に取り付けられ、大きさは2行を占めています.空気清浄機を装着していない車両にはスモッグがあり,(r,c)のスモッグ量はAr,cであった.
1秒以内に、以下に書いたことが順番に発生します.
  • スモッグ拡散.拡散は同時にスモッグのあるすべての部屋で発生した.
  • (r,c)中のスモッグは隣接する4方向に拡散した.
  • 隣接する
  • 方向に空気清浄機があるか、仕切りなし方向に拡散が発生しない.
  • 拡散量はAr,c/5,小数点は破棄である.
  • (r,c)に残留する微塵量はAr,c−(Ar,c/5)であった.×(拡散方向の個数).
  • 空気清浄機が起動します.
  • 空気清浄機に風があります.
  • 上方空気清浄機の風は反時計回りに循環し、下方空気清浄機の風は時計回りに循環する.
  • 風が吹くと、スモッグは風向きに沿って1段移動します.
  • 空気清浄機からの風はスモッグのない風で、空気清浄機に入ったスモッグはすべて浄化されます.
  • 次は拡散の例です.

    空気清浄機の風向は次の方向に循環します.

    部屋の情報を得た後,T秒後,古いリンゴの部屋のスモッグ量を求めた.

    入力


    第1行はR,C,T(6≦R,C≦50,1≦T≦1000)を与える.
    2行目からR行はAr,c(−1≦Ar,c≦1000)である.空気清浄機を設置した場所はAr,c街-1,残りはスモッグ量-1は2番と上下につながっていて、一番上り、下りと2段以上離れています.

    しゅつりょく


    1列目のT秒後、古いリンゴの部屋に残ったスモッグ量を出力します.

    アイデア


    ダストという新しいリストを作成し、拡散したダストを表示し、回転を繰り返します.
    ✔¥コード説明
    1.L秒繰り返します.
    2-1は空気清浄機の位置なので「air」リストに追加します.(無条件列は1列目なのでy値を保存する必要はありません.)
    3.5以上の場合は、上下左右の調査を行い、ホコリに価格を貯める.

  • 空気清浄機の方向に回転します.
    4.1反時計回りの回転
    一番上の列と一番目の空気清浄機がある空間は、一つ一つ押し出されるのと同じなので、一つ一つ押しのけて、尾部要素を保存して削除します.
    4.2時計回りに回転
    上と同様に、2番目の空気清浄機がある空間と最後の行を1つずつ遅らせ、尾部要素を保存して削除します.

  • エンドfor文を用いて,1つずつ遅延する.

  • arrはstoryに更新する必要があります.(このプロセスがない場合は、初期配列状態で繰り返します.)

  • 最後にすべての要素値を加算すると、空気清浄機で-2になるので+2を加算します.
  • マイコードpypy 3


    ::pythonを使用する場合は、タイムアウトしてpypy 3を使用する必要があります。

    import copy
    
    r, c, l = map(int, input().split())
    arr = [list(map(int, input().split())) for x in range(r)]
    
    direction = [[-1, 0], [0, -1], [1, 0], [0, 1]]  #상하좌우 검사
    air = []
    
    for x in range(l):  #l번 반복(l초 후)
        dust = [[0] * c for x in range(r)]
        for i in range(r):
            for j in range(c):
                cnt = 0 #상,하,좌,우 몇 개로 확산됐는지 표시
                if arr[i][j] == -1:
                    air.append(i)
                    continue
                elif arr[i][j] >= 5:    #5보다 작은 경우는 5로 나눈 몫이 0이므로 할 필요 없다.
                    for k in range(4):
                        nx = i + direction[k][0]
                        ny = j + direction[k][1]
                        if 0 <= nx < r and 0 <= ny < c and arr[nx][ny] != -1:   #공기 청정기의 위치는 빼야한다.
                            dust[nx][ny] += arr[i][j]//5
                            cnt += 1
                dust[i][j] += arr[i][j] - (arr[i][j]//5)*cnt
    
        #회전 반시계
        dust[0].append(0)
        l = dust[0][0]
        del dust[0][0]
    
        dust[air[0]].insert(0,0)
        rr = dust[air[0]][-1]
        del dust[air[0]][-1]
    
        lx = air[0]
        rx = 0
        for i in range(air[0]):
            if i == air[0] - 1:
                dust[lx][0] = l
                dust[rx][c-1] = rr
                dust[air[0]][0] = -1    #공기 청정기 위치는 -1로 지정
            else:
                dust[lx][0] = dust[lx-1][0]
                dust[rx][c-1] = dust[rx+1][c-1]
                lx -= 1
                rx += 1
    
        #회전 시계
        dust[air[1]].insert(0, 0)
        rr = dust[air[1]][-1]
        del dust[air[1]][-1]
    
        dust[-1].append(0)
        l = dust[-1][0]
        del dust[-1][0]
    
        lx = air[1]
        rx = r-1
        for i in range(r-air[1]-1):
            if i == r-air[1]-2:
                dust[lx][0] = l
                dust[rx][c-1] = rr
                dust[air[1]][0] = -1    #공기 청정기 위치는 -1로 지정
            else:
                dust[lx][0] = dust[lx+1][0]
                dust[rx][c-1] = dust[rx-1][c-1]
                lx += 1
                rx -= 1
        arr = copy.deepcopy(dust)
    
    print(sum(sum(dust, []))+2)