문제요약
나의 코드 및 설명 01 (노가다.. 성공)
c, r = map(int, input().split())
k = int(input())
if k > c*r:
print(0)
r_list = list(range(r,0,-1))
c_list = list(range(c-1,0,-1))
i = 0
seat = 0
plus_time = 0
while True:
if i > len(r_list)-1 or i > len(c_list)-1:
break
if seat >= k:
break
else:
seat = seat + r_list[i]
plus_time += 1
if seat >= k:
break
else:
seat = seat + c_list[i]
plus_time += 1
i+=1
if k > seat:
if k <= c*r and plus_time % 4 == 0:
x = 1 + plus_time // 4
y = plus_time // 4
print(x,y+abs(seat-k))
elif k <= c*r and plus_time % 4 == 1:
x = 1 + plus_time // 4
y = r - plus_time // 4
print(x+abs(seat-k),y)
elif k <= c*r and plus_time % 4 == 2:
x = c - plus_time // 4
y = r - plus_time // 4
print(x,y-abs(seat-k))
elif k <= c*r and plus_time % 4 == 3:
x = c - plus_time // 4
y = 1 + plus_time // 4
print(x-abs(seat-k),y)
else:
if k <= c*r and plus_time % 4 == 1: #plus time =5 # y값에서 빼기
x = 1 + plus_time // 4
y = r - plus_time // 4
print(x,y-abs(seat-k))
elif k <= c*r and plus_time % 4 == 2: #plustime = 6 x 값에서 빼기
x = c - plus_time // 4
y = r - plus_time // 4
print(x-abs(seat-k),y)
elif k <= c*r and plus_time % 4 == 3: #y에서 더하기
x = c - plus_time // 4
y = 1 + plus_time // 4
print(x,y+abs(seat-k))
elif k <= c*r and plus_time % 4 == 0: # x에서 더하기
x = 1 + plus_time // 4
y = plus_time // 4
print(x+abs(seat-k),y)
나의 코드 및 설명 02 (런타임 에러)
- (1,1) 좌석부터 자리를 올라가며 채울 때, 오른쪽으로 가며 채울 때, 내려오며 채울 때, 왼쪽으로 가며 채울 때를 나누어서 자리를 채우는 메서드를 작성하였다.
- time : 첫 바퀴를 돌면서 자리를 채울 때는 0, 이후 매 바퀴를 돌며 자리를 채울 때마다 +1을 해주었다.
- 이렇게 해서 자리를 모두 채울 수 있었으나 런타임 에러가 떴다..
c, r = map(int, input().split()) #c:가로7 r:세로6
k = int(input())
seat = [[0]*c for _ in range(r)]
time = 0
num = 0
def up():
global time, num
for i in range(time, r-time):
num += 1
seat[i][0+time] = num
def right():
global time, num
for i in range(time+1, c-time):
num += 1
seat[r-1-time][i] = num
def down():
global time, num
for i in range(r-2-time, time-1, -1):
num += 1
seat[i][-(time+1)] = num
def left():
global time, num
for i in range(c-2-time, time,-1):
num += 1
seat[time][i] = num
while True:
if (r+1) // (time+1) < 2:
break
up()
right()
down()
left()
time += 1
x = 0
y = 0
for i in range(r):
for j in range(c):
if seat[i][j] == k:
y,x = i,j
break
if x==0 and y==0:
print(0)
else:
print(x+1,y+1)
다른 코드 및 설명
- 자리를 다 채워놓은 후 자리를 찾는 것이 아니라, 먼저 찾으려는 자리가 주어진 자리 보드 리스트 범위 안에 있는지 확인하고 없다면 0을 출력, 그렇지 않다면 주어진 자리까지 for문을 실행 후 주어진 자리를 찾으면 멈추는 코드를 작성한다.
- dx = [0,1,0,-1] \ dy = [1,0,-1,0] : 첫 번째로는 위로 올라가면서 자리를 채우고 진행중인 방향으로 자리를 더 이상 채울 수 없을 때 시계 방향으로 돌면서 자리를 채우므로, idx = 0 : 위로 진행 / idx = 1 : 우측으로 진행 / idx = 2 : 아래로 진행 /idx = 3 : 왼쪽으로 진행 할 때 각각 x, y 값이 바뀔 수 있도록 코드를 작성하였다.
- for문을 통해 seat(자리 번호)가 1씩 증가하게 했고, 입력받은 k와 일치할 때 현재 좌표를 출력하도록 코드를 작성하였다.
- 만약 seat != k 이라면, 현재 seat 값을 그리드에 저장하고 x, y를 현재 방향과 같은 방향으로 증가시킨다.
만약 증가한 x, y값으로 좌표를 이동시킬 수 없는 상황(x, y가 주어진 그리드의 가로,세로 범위 초과/그리드에 이미 0이 아닌 값이 있는 경우)에는 다시 후진했다가, (direction + 1)%4 을 통해 시계 방향으로 90도 회전 후 전진한다.
이 때, direction + 1를 4로 나누는 이유는 예를들어 direction 이 3인 경우 1을 더하게 되면 direction 리스트의 범위를 초과하게 된다. 따라서 4를 나눈 나머지로 값을 갱신함으로써 범위를 초과하는 것을 방지한다.
c, r = map(int, input().split())
k = int(input())
if k > c*r:
print(0)
exit() #종료
dx = [0,1,0,-1]
dy = [1,0,-1,0]
grid = [[0]*c for _ in range(r)]
direction = x = y = 0
for seat in range(1, c*r + 1):
if seat == k:
print(x+1, y+1)
break
else:
grid[y][x] = seat
x += dx[direction]
y += dy[direction]
if x<0 or y<0 or x>=c or y>=r or grid[y][x] != 0:
x -= dx[direction]
y -= dy[direction]
#범위를 벗어나면 뒤로 뺐다가 방향 바꿔서 전진
direction = (direction+1)%4
x += dx[direction]
y += dy[direction]
피드백
처음 풀었을 때 완전히 노가다로 문제를 해결했다. 두 번째 풀 때는 조금 더 깔끔한 코드로 문제 출제의 의도에 맞게 문제를 해결하고 싶었고, 고민 끝에 자리를 채우는 함수를 만들어서 문제를 해결하면 되겠다고 생각했다. 하지만 예상과는 다르게 런타임 에러가 발생했고, 1시간 30분 정도 문제를 붙잡고 늘어지다가 결국 다른 사람의 코드를 참고할 수 밖에 없었다.
런타임 에러가 발생하는 것을 방지하기 위해 딱 찾으려는 자리 만큼만 반복문을 수행하고, 자리를 더 이상 놓을 수 없는 상황일 때엔 시계방향으로 90도 회전하는 코드가 인상깊었다.
백준 문제를 풀면서 dx, dy를 통해 회전하여 전진하는 코드가 상당히 많이 활용되는 것을 알 수 있었다. 꾸준히 숙달하여 비슷한 문제를 주어졌을 때 해결할 수 있도록 해야겠다.
'Baekjoon > IM Level' 카테고리의 다른 글
[백준] 1158 요세푸스 문제 (실버4) / 큐 (0) | 2023.03.24 |
---|---|
[백준] 2491 수열 (실버4) / DP(다이나믹 프로그래밍) (0) | 2023.03.24 |
[백준] 14696 딱지놀이 (브론즈1) / 리스트 간의 비교연산자 (0) | 2023.03.23 |
[백준] 17413 단어 뒤집기2 (실버3) / 스택, isalnum(), join(), split() 함수 (0) | 2023.03.23 |
[백준] 9655 돌 게임 (실버5) / DP(다이나믹 프로그래밍) (0) | 2023.03.23 |