

생각해줘야 할 부분들이 많아서 조금 까다로웠지만 나름 재미있었다.
처음에는 일단 다 그려놓고 입력받은 사이즈에 맞춰서 출력하면 되지 않을까 싶었는데, 소용돌이의 최대 크기가 10000x10000이라 다 그리다간 시간 초과 아니면 메모리 초과 둘 중 하나는 무조건 뜰 거라고 생각했다.
따라서 연산 횟수를 줄이는게 불가피했는데, 어떻게 줄여볼까 하다가 (0,0)을 기준으로 오른쪽 아래 대각선이 모두 제곱수인 걸 이용하기로 했다. 사실 처음에는 직관으로 제곱수를 골라 해결한 감이 있지만, 곰곰히 생각해보니 소용돌이의 한 cycle이 제곱수로 끝나기 때문에 제곱수를 기준으로 문제를 해결하는 것이 맞다고 생각했다.
대각선이니까 x,y좌표는 똑같고, 좌표값을 n이라고 하면 그 칸에 오는 제곱수는 (2*n+1)^2였다. 그 칸에는 제곱수를 집어넣고, 나머지는 제곱수를 기준으로 칸의 좌표를 고려해서 해당 칸의 값을 계산했다.
깔끔하게 출력해야하는 부분이 좀 짜증났다. 처음에는 저 부분을 제대로 안 보고 제출했다가 출력 형식에서 틀려서 뭘 잘못했나 둘러봤다. 과제로 프로젝트를 하거나, 타 학교 친구들 과제를 도와줄 때 항상 열 받는게 문자열 포맷팅이다. 출력해야하는 소용돌이의 가장 큰 수를 기준으로 최대 자릿수를 계산해 포맷팅해서 출력했다.
다음은 문제를 해결한 코드이다.
r1,c1,r2,c2=map(int,input().split())
L=[[0 for i in range(c2-c1+1)] for j in range(r2-r1+1)]
for i in range(c1,c2+1):
x=i-c1
k=abs(i)
for j in range(r2,r1-1,-1):
y=j-r1
if i==j and j>0:
L[y][x]=(2*k+1)**2
elif i<=0 and -k<=j<=k:
L[y][x]=(2*k+1)**2-2*k-(k-j)
elif i>0 and -k<=j<=k:
L[y][x]=(2*k+1)**2-8*k+(k-j)
elif j>0:
L[y][x]=(2*j+1)**2-(j-i)
elif j<0:
L[y][x]=(2*abs(j)+1)**2-6*abs(j)+(abs(j)-i)
k=0
for i in L:
k=max(k,max(i))
p=0
while k>0:
p+=1
k//=10
for i in L:
for j in i:
print(str(j).rjust(p,' '),end=' ')
print()
사실 이런 구현 문제를 별로 좋아하진 않는다.
알고리즘과는 다르게 구현 문제는 한 번 방향이 엇나가면 혼자서 점점 늪에 빠지기 때문에,,,
그나마 이번 문제는 직관으로 해결법을 쉽게 찾아서 비교적 빠르게 해결할 수 있었던 것 같다.
반복문 범위도 더럽고 코드도 깔끔하지 못한데, 이는 항상 문제를 풀 때 Trial and Error 방식으로 풀어서 그런 것 같다. 사실 이렇게 블로그를 통해 생각을 정리하는 것이 그 때문이기도 하다. 나중에 내 코드를 보면 알아보기 힘들 때가 많아서,,
'BOJ' 카테고리의 다른 글
백준(BOJ) 1167 트리의 지름(Python) (0) | 2022.07.08 |
---|---|
백준(BOJ) 2448 별 찍기 - 11(Python) (0) | 2022.07.08 |
백준(BOJ) 7662 이중 우선순위 큐(Python) (0) | 2022.07.08 |
백준(BOJ) 3866 풍선 수집(Python) (0) | 2022.07.08 |
백준(BOJ) 1132 합(Python) (0) | 2022.07.08 |