## 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)
## 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, 0, 5, 0]
tree.remove(0)
## 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번: 미세먼지 안녕!
#### 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
## 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
[[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))
[[[[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)]],
[[], [], [], []]]
[[], [], [], []]
[[(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)]]
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [1, -1, 3]]
[[], [[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], [...]]
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]])
[[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]
- 체스판에 대한 정보
- 말에 대한 정보 (번호, 위치, 방향)
- 방식 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]]], [[], [], [], []]]
[[0, 0], [1, 0], [2, 0], [0, 0], [1, 0], [2, 0]]
[[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
#### 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)
[[[],
[],
[<__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
-----