Skip to content

Latest commit

 

History

History
1508 lines (899 loc) · 31.2 KB

_백준_강의_연습(8)_시뮬레이션과_구현_1.ipynb.md

File metadata and controls

1508 lines (899 loc) · 31.2 KB

16234번: 인구 이동

## 16234번: 인구 이동
#### https://www.acmicpc.net/problem/16234


from collections import deque

dx =[0, 0, -1, 1]
dy =[-1, 1, 0, 0]

## BFS 탐색 이용
def bfs(a, L, R):
    n = len(a)
    c = [[False]*n for _ in range(n)] ## 방문 여부 표시할 배열
    ok = False ## 인구이동 발생했는지 여부
    #q = deque()

    for i in range(n):
        for j in range(n):
            if c[i][j] == False:
                q = deque()
                q.append((i,j))
                c[i][j] = True

                s = [(i, j)] # 연합을 이루는 국가의 좌표를 담아둘 리스트 선언
                total = a[i][j] # 연합을 이루는 국가의 인구수 합 담을 변수


                while q:
                    x, y = q.popleft()

                    for k in range(4):
                        nx,ny = x+dx[k], y+dy[k]

                        if 0 <= nx < n and 0 <= ny < n and c[nx][ny] == False: # 범위 안에 있고 && 아직 방문한 적 없다면
                              diff = abs(a[x][y] - a[nx][ny])

                              if L <= diff <= R: ## 문제 조건 만족한다면
                                  # 방문 수행
                                  q.append((nx,ny))
                                  s.append((nx,ny))
                                  c[nx][ny] = True

                                  ok = True
                                  total += a[nx][ny]


                # 연합 & 인구 변경
                val = total // len(s) # (문제 조건) 편의상 소수점은 버린다.

                for x,y in s:
                    a[x][y] = val


    return ok ## 인구이동 발생했는지 여부 리턴                            




# 입력
n, L, R = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(n)]

# 답 구하기
ans = 0 # 인구이동 총 발생 횟수
while True:
    ## 1) 인구이동 발생했으면
    if bfs(a, L, R) == True:
        ans += 1 ## 발생횟수 +1

    ## 2) 발생하지 않았으면
    else:
        break ## (조기 종료)


print(ans)
2 40 50
50 30
20 40
0

16235번: 나무 재테크

## 16235번: 나무 재테크
#### https://www.acmicpc.net/problem/16235



# 인접한 8방향 칸
dx = [-1, -1, -1, 0, 0, 1, 1, 1]
dy = [-1, 0, 1, -1, 1, -1, 0, 1]

# 입력
n, m, k = map(int, input().split())
a = [list(map(int, input().split())) for _ in range(n)]
d = [[5]*n for _ in range(n)] ## 양분 배열 (가장 처음에 양분은 모든 칸에 5만큼 들어있다.)
tree = [ [[] for j in range(n)]  for i in range(n)] # tree[r][c][나무의 나이 리스트] -> 3차원 배역

for _ in range(m):
    x, y, age = map(int, input().split())
    tree[x-1][y-1].append(age)




# K년 반복
for _ in range(k):
    p = [[0]*n for _ in range(n)] ## 매년 가을에 새로 추가할 나무의 개수 저장할 임시 배열

    for i in range(n):
        for j in range(n):
            temp = [] ### 매년 한해 동안 각 (r,c)칸 당 나무들의 나이 리스트를 임시저장할 리스트
            tree[i][j].sort()
            dead = 0

            ## 봄
            # 만약, 땅에 양분이 부족해 자신의 나이만큼 양분을 먹을 수 없는 나무는 양분을 먹지 못하고 즉시 죽는다.
            for x in tree[i][j]:
                if d[i][j] >= x:
                    d[i][j] -= x
                    temp.append(x+1) ### 봄에 조건에 해당되는 나무의 나이 1 증가
                    

                    ## 가을�
                    # 번식하는 나무는 나이가 5의 배수이어야 하며, 인접한 8개의 칸에 나이가 1인 나무가 생긴다.
                    if (x+1) % 5 == 0:
                        for k in range(8):
                            nx, ny = i+dx[k], j+dy[k]

                            if 0<=nx<n and 0<=ny<n:
                                p[nx][ny] += 1 ### 가을에 새로 심어지는 나이가 1인 나무의 개수 +1

                else: # 즉시 죽는다.
                    dead += x // 2 # 여름에 양분으로 추가될 봄에 죽은 나무의 양분 합
                    # 여름에는 봄에 죽은 나무가 양분으로 변하게 된다. 각각의 죽은 나무마다 나이를 2로 나눈 값이 나무가 있던 칸에 양분으로 추가된다. 소수점 아래는 버린다.
                    
                    ### 봄에 즉시 죽는 나무는 여기서 temp[r][c][] 배열에서 빠짐 


            tree[i][j] = temp ### 임시 저장한 나무들의 나이 리스트 업데이트


            ## 여름
            d[i][j] += dead


            ## 겨울
            d[i][j] += a[i][j]


    ## 가을 -> 다음 해 새로 심어지는 나이가 1인 나무 추가하기
    for i in range(n):
        for j in range(n):
            for k in range(p[i][j]):
                tree[i][j].append(1)



# 답 출력
ans = 0
for i in range(n):
    for j in range(n):
        ans += len(tree[i][j])


print(ans)
5 2 1
2 3 2 3 2
2 3 2 3 2
2 3 2 3 2
2 3 2 3 2
2 3 2 3 2
2 1 3
3 2 3
15
tree = [1, 5, 4]
del tree[1]
tree
[1, 4]
tree = [1, 0, 5, 0]

tree.remove(0)
tree
[1, 5, 0]

17140번: 이차원 배열과 연산

## 17140번: 이차원 배열과 연산
#### https://www.acmicpc.net/problem/17140



import sys
from collections import defaultdict


n = 3 # 시작 행의 크기
m = 3 # 시작 열의 크기

a = [[0]*100 for _ in range(100)]


r, c, k = map(int, input().split())
r -= 1
c -= 1


# 행 또는 열의 크기가 100을 넘어가는 경우에는 처음 100개를 제외한 나머지는 버린다.

# 100 x 100 크기에 맞게 입력 a배열 담기
for i in range(n):
    temp = list(map(int, input().split())) # 입력

    for j in range(m):
        a[i][j] = temp[j]



# 답 구하기
if a[r][c] == k: ## 시행 전 답을 찾으면
    print(0)
    sys.exit(0)



for t in range(1, 101):
    ## R 연산 (행)
    if n >= m:
        mm = m
        for i in range(n):
            d = defaultdict(int)

            for j in range(n): ######## why ?? ########
                if a[i][j] == 0:
                    continue
                d[a[i][j]] += 1 # 등장횟수 1 추가

            ## 정렬
            v = []
            for key, val in d.items():
                v.append((val, key)) ## 튜플로 저장: (등장 횟수, 숫자)
            v.sort() ## 수의 "등장 횟수"가 커지는 순으로, 그러한 것이 여러가지면 "수"가 커지는 순으로 정렬


            ### 이차원 배열 a 채우기
            l = min(len(v), 50) # 최대는 50쌍 -> 100칸

            for j in range(l):
                a[i][j*2] = v[j][1] ## 수 (key)
                a[i][j*2+1] = v[j][0] ## 등장 횟수 (val)

            for j in range(l*2, 100):
                a[i][j] = 0 ## 나머지 칸은 0 채우기


            ## 다음에 적용할 열의 개수 변경
            if mm < len(v)*2:
                mm = len(v)*2


        m = mm


    ## C 연산
    else:
        nn = n
        for j in range(m):
            d = defaultdict(int)
            for i in range(n):
                if a[i][j] == 0:
                    continue

                d[a[i][j]] += 1

            ## 정렬
            v = []
            for key, val in d.items():
                v.append((val, key))
            v.sort()


            ### 이차원 배열 a 채우기
            l = min(len(v), 50)

            for i in range(l):
                a[i*2][j] = v[i][1]
                a[i*2+1][j] = v[i][0]

            for i in range(l*2, 100):
                a[i][j] = 0


            ## 다음에 적용할 열의 개수 변경
            if nn < len(v)*2:
                nn = len(v)*2
                

        n = nn


    ## 시행 후 답 찾는지 체크
    if a[r][c] == k:
        print(t)
        sys.exit(0)

    


print(-1) # 100번 이내에 끝까지 못찾으면 -1 출력
10 4 3
1 3 5
2 4 6
7 5 2
10



An exception has occurred, use %tb to see the full traceback.


SystemExit: 0



/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:2890: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

17144번: 미세먼지 안녕!

## 17144번: 미세먼지 안녕!
#### https://www.acmicpc.net/problem/17144


# 입력
r, c, t = map(int, input().split())


a = [list(map(int, input().split())) for _ in range(r)] # 미세먼지 정보

# 공기청정기 위치 찾기
for i in range(r):
    if a[i][0] == -1:
        x = i
        y = 0
        break



## 반시계/시계방향
dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]


## 정보 임시 저장 배열
b = [[0]*c for _ in range(r)]



def go(sx, sy, z):
    prev = 0

    x = sx
    y = sy+1
    k = 0

    while True:
        if x==sx and y==sy:
            break # 한 바퀴 다 돌면


        temp = prev
        prev = a[x][y]
        a[x][y] = temp

        x += dx[k]
        y += dy[k]
        if x<0 or x>=r or y<0 or y>=c: # 처음 범위를 벗어나면
            ## 이전 칸으로 돌아와서
            x -= dx[k]
            y -= dy[k]

            ## 다음 방향으로 바꾸어 진행
            k = (k+z) % 4
            x += dx[k]
            y += dy[k]






# T초가 지난 후 방에 남아있는 미세먼지의 양을 구하기
for _ in range(t):
    ## 1단계: 미세먼지의 인접 칸 확산
    for i in range(r):
        for j in range(c):
            if a[i][j] == -1 or a[i][j] == 0:
                continue


            cnt = 0 ## 적용되는 칸의 전체 개수 세기
            for k in range(4):
                nx, ny = i+dx[k], j+dy[k]

                ## (조건) 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
                if 0<=nx<r and 0<=ny<c:
                    if a[nx][ny] != -1:
                        cnt += 1


            if cnt > 0:
                val = a[i][j] // 5

                for k in range(4):
                    nx, ny = i+dx[k], j+dy[k]

                    ## (조건) 인접한 방향에 공기청정기가 있거나, 칸이 없으면 그 방향으로는 확산이 일어나지 않는다.
                    if 0<=nx<r and 0<=ny<c:
                        if a[nx][ny] != -1:
                            b[nx][ny] += val ## 확산 수행 후 계산 값 b에 저장


            a[i][j] = a[i][j] - val*cnt



    for i in range(r):
        for j in range(c):
            if a[i][j] == -1 or b[i][j] == 0:
                continue

            a[i][j] += b[i][j]
            b[i][j] = 0 ## b정보 다시 초기화


    ## 2단계: 공기청정기에서 부는 반시계/시계 방향 바람에 따른 미세먼지 이동
    # 반시계
    go(x, y, 1)
    # 시계
    go(x+1, y, 3)



# 답 출력
ans = 0

for i in range(r):
    for j in range(c):
        if a[i][j] == -1:
            continue

        ans += a[i][j]


print(ans)
7 8 1
0 0 0 0 0 0 0 9
0 0 0 0 3 0 0 8
-1 0 5 0 0 0 22 0
-1 8 0 0 0 0 0 0
0 0 0 0 0 10 43 0
0 0 5 0 15 0 0 0
0 0 40 0 0 0 20 0
188
print(x, y)
2 0

17780번: 새로운 게임

## 17780번: 새로운 게임
#### https://www.acmicpc.net/problem/17780


# 내가 처음 시도한 풀이 (실패)


import sys



# 입력
n, k = map(int, input().split())

a = [list(map(int, input().split())) for _ in range(n)]

horse = []
for _ in range(k):
    r, c, dir = map(int, input().split())
    horse.append([r-1, c-1, dir-1])


## 말 리스트 저장할 NxN 배열
b = [[[]]*n for _ in range(n)]

for i in range(k):
    r, c, dir = horse[i]
    b[r][c].append([i, dir])



# 방향
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]




# 게임 수행
for turn in range(1, 1001):
    # 해당 턴에서 말 이동
    #(조건)턴 한 번은 1번 말부터 K번 말까지 순서대로 이동시키는 것이다.
    for i in range(k):
        r, c, dir = horse[i]

        ##(조건)가장 아래에 있는 말만 이동할 수 있다.
        ## i번째 말이 현재 가장 아래에 있는 말이 아닐 경우, 다음 번호로 pass
        if b[r][c][0] == i:
        

            nx = r + dx[dir]
            ny = c + dy[dir]


            ## 범위를 벗어나는 경우
            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                if dir==0:
                    dir = 1
                elif dir==1:
                    dir = 0
                elif dir==2:
                    dir = 3
                elif dir==3:
                    dir=2

                horse[i][1] = dir



                if 0<=nx<n and 0<=ny<n and a[nx+dx[dir]][ny+dy[dir]] != 2:
                    nx = nx+dx[dir]
                    ny = ny+dy[dir]
                    

                    ## 흰색 칸
                    if a[nx][ny] == 0:
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []



                    ## 빨간색 칸
                    if a[nx][ny] == 1:
                        b[r][c].sort(reverse=True)
                        b[nx][ny].extend(b[r][c])


            
            ## 흰색 칸
            if a[nx][ny] == 0:
                b[nx][ny].extend(b[r][c])
                

                for h in b[r][c]:
                    horse[h[0]][0] = nx
                    horse[h[0]][1] = ny


                b[r][c] = []


            ## 빨간색 칸
            if a[nx][ny] == 1:
                b[r][c].sort(reverse=True)
                b[nx][ny].extend(b[r][c])
                

                for h in b[r][c]:
                    horse[h[0]][0] = nx
                    horse[h[0]][1] = ny
                    

                b[r][c] = []




            ## 파란색 칸
            if a[nx][ny] == 2:
                if dir==0:
                    dir = 1
                elif dir==1:
                    dir = 0
                elif dir==2:
                    dir = 3
                elif dir==3:
                    dir=2

                horse[i][1] = dir

                # 방향 바꾼 후, 두번째 이동 칸에 대하여 체크
                if 0<=nx<n and 0<=ny<n and a[nx+dx[dir]][ny+dy[dir]] != 2:
                    nx = nx+dx[dir]
                    ny = ny+dy[dir]
                    

                    ## 흰색 칸
                    if a[nx][ny] == 0:
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []



                    ## 빨간색 칸
                    if a[nx][ny] == 1:
                        b[r][c].reverse()
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []


                    ## 파란색 칸 -> 그대로 stop
                    ## 범위 넘어가도 -> 그냥 pass

        


    # 게임 종료되는지 체크
    for i in range(n):
        for j in range(n):
            if len(b[i][j]) >= 4:
                print(turn)
                sys.exit(0)

print(-1)
4 4
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1
1 2 1
1 3 1
3 3 3
-1
horse
[[0, 0, 0], [0, 1, 0], [0, 2, 0], [2, 2, 2]]
for i in range(k):
    r, c, dir = horse[i]
    b[r][c].append((i, dir))
b
[[[[0, 0], [1, 0], [2, 0], (0, 0), (1, 0), (2, 0)],
  [[0, 0], [1, 0], [2, 0], (0, 0), (1, 0), (2, 0)],
  [[0, 0], [1, 0], [2, 0], (0, 0), (1, 0), (2, 0)],
  [[0, 0], [1, 0], [2, 0], (0, 0), (1, 0), (2, 0)]],
 [[], [], [], []],
 [[[3, 2], (3, 2)], [[3, 2], (3, 2)], [[3, 2], (3, 2)], [[3, 2], (3, 2)]],
 [[], [], [], []]]
for row in b:
    print(row)
[[], [], [], []]
[[(0, 0), (2, 0)], [(0, 0), (2, 0)], [(0, 0), (2, 0)], [(0, 0), (2, 0)]]
[[(1, 2)], [(1, 2)], [(1, 2)], [(1, 2)]]
[[(3, 1)], [(3, 1)], [(3, 1)], [(3, 1)]]
a
horse
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [1, -1, 3]]
for row in b:
    print(row)
[[], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]]
[[[3, 2]], [[3, 2]], [[3, 2]], [[3, 2]]]
[[[3, 2]], [[3, 2]], [], [[3, 2]]]
[[], [], [], []]
b[2][1]
[[3, 2]]
b[0][0]
[[0, 0], [1, 0], [2, 0], [...]]
for h in b[0][0]:
    print(h)
[0, 0]
[1, 0]
[2, 0]
[[0, 0], [1, 0], [2, 0], [...]]
ls = [[0, 0],
[1, 0],
[2, 0]]

ls.extend([[0, 0], [1, 0], [2, 0]])
ls
[[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]

필요한 정보

  1. 체스판에 대한 정보
  • board[i][j]
  1. 말에 대한 정보 (번호, 위치, 방향)
  • 방식 1) a[i][j] = (i,j)에 있는 말을 저장
  • 장점: 어떤 곳 어떤 말이 있는지 알아내기 쉽다.
  • 단점: 어떤 말이 어디에 있는지 알려면 모든 i, j에 대해 탐색해야 한다.

  • 방식 2) where[i] = i번 말의 위치
  • 장점: 어떤 말(특정)이 어디에 있는지 알아내기 쉽다.
  • 단점: 어떤 위치에 어떤 말이 있는지 알아내기 어렵다.
# 정답


import sys

class Piece:
    def __init__(self, no, dir):
        self.no = no
        self.dir = dir



# 입력
n, k = map(int, input().split())

a = [list(map(int, input().split())) for _ in range(n)]



## 말 리스트 저장할 NxN 배열
b = [[ [] for j in range(n)] for i in range(n)]

horse = [None] * k
for i in range(k):
    r, c, dir = map(int, input().split())

    b[r-1][c-1].append(Piece(i, dir-1))
    horse[i] = (r-1, c-1)





# 방향
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]





def opposite(dir): # 방향 바꾸는 함수
    if dir==0:
        return 1
    elif dir==1:
        return 0
    elif dir==2:
        return 3
    elif dir==3:
        return 2


def go(b, horse, x, y, nx, ny):
    for h in b[x][y]:
        b[nx][ny].append(h)
        horse[h.no] = (nx, ny)

    b[x][y].clear()



# 게임 수행
for turn in range(1, 1001):
    # 해당 턴에서 말 이동
    #(조건)턴 한 번은 1번 말부터 K번 말까지 순서대로 이동시키는 것이다.
    for i in range(k):
        x, y = horse[i]

        if b[x][y][0].no != i: #(조건)가장 아래에 있는 말만 이동할 수 있다.
            continue
        
        elif b[x][y][0].no == i: #(조건)가장 아래에 있는 말만 이동할 수 있다.
            dir = b[x][y][0].dir
            nx = x + dx[dir]
            ny = y + dy[dir]



            if 0<=nx<n and 0<=ny<n:
                if a[nx][ny] == 2: ## (3)이동하려는 칸이 파란색이면 일단 방향을 바꿔둔다.
                    b[x][y][0].dir = opposite(dir)

            else: ## (4)체스판을 벗어나는 경우에는 파란색과 같은 경우이다.
                b[x][y][0].dir = opposite(dir)



            # 다음 진행
            dir = b[x][y][0].dir
            nx = x + dx[dir]
            ny = y + dy[dir]


            if 0<=nx<n and 0<=ny<n:
                if a[nx][ny] == 0: ## (1)흰색
                    go(b, horse, x, y, nx, ny)

                elif a[nx][ny] == 1: ## (2)빨간색
                    b[x][y].reverse()
                    go(b, horse, x, y, nx, ny)




                # 탐색 다시 안하고, b에 리스트 확장할 때 길이 4개 넘는지 바로 같이 체크
                if len(b[nx][ny]) >= 4:
                    print(turn)
                    sys.exit(0)



            else: # 범위를 벗어나면 -> 그냥 넘어간다(?)
                pass
                        


print(-1)
4 4
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1
1 2 1
1 3 1
3 3 3
2



An exception has occurred, use %tb to see the full traceback.


SystemExit: 0



/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:2890: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
# 내가 처음 시도한 풀이 (수정, 실패)


import sys



# 입력
n, k = map(int, input().split())

a = [list(map(int, input().split())) for _ in range(n)]

horse = []
for _ in range(k):
    r, c, dir = map(int, input().split())
    horse.append([r-1, c-1, dir-1])


## 말 리스트 저장할 NxN 배열
b = [[[]]*n for _ in range(n)]

for i in range(k):
    r, c, dir = horse[i]
    b[r][c].append([i, dir])



# 방향
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]




# 게임 수행
for turn in range(1, 1001):
    # 해당 턴에서 말 이동
    #(조건)턴 한 번은 1번 말부터 K번 말까지 순서대로 이동시키는 것이다.
    for i in range(k):
        r, c, dir = horse[i]

        ##(조건)가장 아래에 있는 말만 이동할 수 있다.
        ## i번째 말이 현재 가장 아래에 있는 말이 아닐 경우, 다음 번호로 pass
        if b[r][c][0][0] == i:
            #print(i)
        

            nx = r + dx[dir]
            ny = c + dy[dir]


            ## 범위를 벗어나는 경우
            if nx < 0 or nx >= n or ny < 0 or ny >= n:
                if dir==0:
                    dir = 1
                elif dir==1:
                    dir = 0
                elif dir==2:
                    dir = 3
                elif dir==3:
                    dir=2

                horse[i][1] = dir



                if 0<=nx<n and 0<=ny<n and a[nx+dx[dir]][ny+dy[dir]] != 2:
                    nx = nx+dx[dir]
                    ny = ny+dy[dir]
                    

                    ## 흰색 칸
                    if a[nx][ny] == 0:
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []



                    ## 빨간색 칸
                    if a[nx][ny] == 1:
                        b[r][c].sort(reverse=True)
                        b[nx][ny].extend(b[r][c])


            
            ## 흰색 칸
            if a[nx][ny] == 0:
                b[nx][ny].extend(b[r][c])
                

                for h in b[r][c]:
                    horse[h[0]][0] = nx
                    horse[h[0]][1] = ny


                b[r][c] = []


            ## 빨간색 칸
            if a[nx][ny] == 1:
                b[r][c].sort(reverse=True)
                b[nx][ny].extend(b[r][c])
                

                for h in b[r][c]:
                    horse[h[0]][0] = nx
                    horse[h[0]][1] = ny
                    

                b[r][c] = []




            ## 파란색 칸
            if a[nx][ny] == 2:
                if dir==0:
                    dir = 1
                elif dir==1:
                    dir = 0
                elif dir==2:
                    dir = 3
                elif dir==3:
                    dir=2

                horse[i][1] = dir

                # 방향 바꾼 후, 두번째 이동 칸에 대하여 체크
                if 0<=nx<n and 0<=ny<n and a[nx+dx[dir]][ny+dy[dir]] != 2:
                    nx = nx+dx[dir]
                    ny = ny+dy[dir]
                    

                    ## 흰색 칸
                    if a[nx][ny] == 0:
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []



                    ## 빨간색 칸
                    if a[nx][ny] == 1:
                        b[r][c].reverse()
                        b[nx][ny].extend(b[r][c])
                        

                        for h in b[r][c]:
                            horse[h[0]][0] = nx
                            horse[h[0]][1] = ny

                        b[r][c] = []


                    ## 파란색 칸 -> 그대로 stop
                    ## 범위 넘어가도 -> 그냥 pass

        


    # 게임 종료되는지 체크
    for i in range(n):
        for j in range(n):
            if len(b[i][j]) >= 4:
                print(turn)
                sys.exit(0)

print(-1)
4 4
0 0 2 0
0 0 1 0
0 0 1 2
0 2 0 0
2 1 1
3 2 3
2 2 1
4 1 3
0
1
3
1



An exception has occurred, use %tb to see the full traceback.


SystemExit: 0



/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:2890: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
1## 결과 확인

for row in b:
    print(b)
[[[], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]], [[[3, 2]], [[3, 2]], [[3, 2]], [[3, 2]]], [[[3, 2]], [[3, 2]], [], [[3, 2]]], [[], [], [], []]]
[[[], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]], [[[3, 2]], [[3, 2]], [[3, 2]], [[3, 2]]], [[[3, 2]], [[3, 2]], [], [[3, 2]]], [[], [], [], []]]
[[[], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]], [[[3, 2]], [[3, 2]], [[3, 2]], [[3, 2]]], [[[3, 2]], [[3, 2]], [], [[3, 2]]], [[], [], [], []]]
[[[], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]], [[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]], [[[3, 2]], [[3, 2]], [[3, 2]], [[3, 2]]], [[[3, 2]], [[3, 2]], [], [[3, 2]]], [[], [], [], []]]
b[0][1]
[[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]
horse
[[0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 2, 2]]
n = 4
b = [[[]]*n for _ in range(n)]

for row in b:
    print(row)
n = 4
bb = [ [[] for j in range(n)]  for i in range(n)]

for row in b:
    print(row)
[[], [], [], []]
[[], [], [], []]
[[], [], [], []]
[[], [], [], []]

17837번: 새로운 게임 2

## 17837번: 새로운 게임 2
#### https://www.acmicpc.net/problem/17837


# 턴 한 번은 1번 말부터 K번 말까지 순서대로 이동시키는 것이다. 한 말이 이동할 때 위에 올려져 있는 말도 함께 이동한다.
# (하지만, 가장 아래에 있는 말만 이동할 수 있다. 조건 빠짐)


# 정답


import sys

class Piece:
    def __init__(self, no, dir):
        self.no = no
        self.dir = dir



# 입력
n, k = map(int, input().split())

a = [list(map(int, input().split())) for _ in range(n)]



## 말 리스트 저장할 NxN 배열
b = [[ [] for j in range(n)] for i in range(n)]

horse = [None] * k
for i in range(k):
    r, c, dir = map(int, input().split())

    b[r-1][c-1].append(Piece(i, dir-1))
    horse[i] = (r-1, c-1, len(b[r-1][c-1])-1) ## k개의 말 정보 리스트에 "순서" 정보도 추가로 저장해야 함 !!
    ## len(b[r-1][y-1]-1) : 현재까지 담겨진 체스 말 리스트 길이 -1이 index번째 순서 정보





# 방향
dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]





def opposite(dir): # 방향 바꾸는 함수
    if dir==0:
        return 1
    elif dir==1:
        return 0
    elif dir==2:
        return 3
    elif dir==3:
        return 2


def go(b, horse, x, y, nx, ny, index):
    for h in b[x][y][index:]:
        b[nx][ny].append(h)
        horse[h.no] = (nx, ny, len(b[nx][ny])-1) ## 순서 번호 다시 붙음

    #####b[x][y].clear()
    b[x][y] = b[x][y][:index] ## 현재 index번째 아래 말들만 남음



# 게임 수행
for turn in range(1, 1001):
    # 해당 턴에서 말 이동
    #(조건)턴 한 번은 1번 말부터 K번 말까지 순서대로 이동시키는 것이다.
    for i in range(k):
        x, y, index = horse[i]

        #####if b[x][y][0].no != i: #(조건)가장 아래에 있는 말만 이동할 수 있다.
            #####continue
        
        #####elif b[x][y][0].no == i: #(조건)가장 아래에 있는 말만 이동할 수 있다.

        dir = b[x][y][index].dir
        nx = x + dx[dir]
        ny = y + dy[dir]



        if 0<=nx<n and 0<=ny<n:
            if a[nx][ny] == 2: ## (3)이동하려는 칸이 파란색이면 일단 방향을 바꿔둔다.
                b[x][y][index].dir = opposite(dir)

        else: ## (4)체스판을 벗어나는 경우에는 파란색과 같은 경우이다.
            b[x][y][index].dir = opposite(dir)



        # 다음 진행
        dir = b[x][y][index].dir
        nx = x + dx[dir]
        ny = y + dy[dir]


        if 0<=nx<n and 0<=ny<n:
            if a[nx][ny] == 0: ## (1)흰색
                go(b, horse, x, y, nx, ny, index) ## 현재 몇 번재 순서인지 정보도 추가 필요 !

            elif a[nx][ny] == 1: ## (2)빨간색
                #####b[x][y].reverse()
                b[x][y] = b[x][y][:index] + b[x][y][index:][::-1]
                ## 현재 해당 말의 인덱스 아래 말들은 그대로 유지되고, 위에 말들에만 뒤집기가 적용됨 !
                go(b, horse, x, y, nx, ny, index) ## 현재 몇 번재 순서인지 정보도 추가 필요 !





            # 탐색 다시 안하고, b에 리스트 확장할 때 길이 4개 넘는지 바로 같이 체크
            if len(b[nx][ny]) >= 4:
                print(turn)
                sys.exit(0)



        else: # 범위를 벗어나면 -> 그냥 넘어간다(?)
            pass
                        


print(-1)
4 4
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1
1 2 1
1 3 1
3 3 3
2



An exception has occurred, use %tb to see the full traceback.


SystemExit: 0



/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:2890: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
b
[[[],
  [],
  [<__main__.Piece at 0x7f75f5f73f90>,
   <__main__.Piece at 0x7f75f5c05710>,
   <__main__.Piece at 0x7f75efe74f90>,
   <__main__.Piece at 0x7f75efe79050>],
  []],
 [[], [], [], []],
 [[], [], [], []],
 [[], [], [], []]]
index = 2

for h in b[0][2][index:]:
    #b[nx][ny].append(h)
    #horse[h.no] = (nx, ny, len(b[nx][ny])-1) ## 순서 번호 다시 붙음
    print(h)
    print(h.no)
    print(h.dir)
    print('-----')

#####b[x][y].clear()
#b[x][y] = b[x][y][:index] ## 현재 index번째 아래 말들만 남음
<__main__.Piece object at 0x7f75efe74f90>
2
1
-----
<__main__.Piece object at 0x7f75efe79050>
3
2
-----