https://swexpertacademy.com/main/main.do
(12/23일에 푼 문제다;; ㅋㅋ)
문제를 첨 보자마자 헉 했다..
이걸 어떻게 풀지..
그래서 가장 먼저 모범답안을 봤다.
내 기준 모범답안은 실행시간이 가장 짧은 것이었다.
아래 답안은 samsungsh 님의 답안이다.
- 51,668 kb메모리
- 107 ms실행시간
사실 이걸 봐도 바로 아..! 하고 느낌이 오지 않는다.
특히 for문 두개의 중첩은 더더욱..
그래서 메모에 하나씩 써가며 분석했다.
위에 코드의 해설을 다음과 같다.(예시로 n=3인 경우를 들었다)
먼저 변수 T를 입력받고 T 범위만큼의 for문을 돌린다.(test case)
행렬의 길이인 n을 받는다.
arr라는 빈 리스트를 만든다.
dir이라는 리스트는 90,180,270 원소가 차례대로 배열되어있는 리스트이다.
dir을 이렇게 설정해준 이유는 dir 내부의 원소들을 상대로 for문을 돌렸을 때 90,180,270을 차례로 실행시키기 위해서다.(for case in dir)
그 다음 for _ in range(n) … 은
1 2 3
4 5 6
7 8 9
이렇게 입력된 값들을 (예시)
arr = [['1','2','3'],['4','5','6'],['7','8','9']]
이렇게 만들어준다.
for i in range(n)은 한줄 한줄을 만들어주는 for문이다.
따라서 이 for문에 종속되어 있는 명령문들은
741 987 369
852 654 258
963 321 147
각각의 한줄을 만드는데 필요한 명령문들이다.
다시 말해 i=0이면 첫번째 문장이 만들어진다.
result는 출력되는 문장의 초기값이다.
for case in dir: 이 뒤에 부터 아까 dir = [90,180,270]으로 설정한 이유가 드러난다.
if case==90: 이면
7 4 1
8 5 2
9 6 3
첫번째 7 4 1 만 보자.
숫자 배열이 이렇게 된다.
'741' = arr[2][0] + arr[1][0] + arr[0][0]
여기서 arr[j][0]
j 자리만 바뀐다.
'852' = arr[2][1] + arr[1][1] + arr[0][1]
여기서도 arr[j][1]
j 자리만 바뀐다.
'963' = arr[2][2] + arr[1][2] + arr[0][2]
여기서 arr[j][2]
j 자리만 바뀐다.
그래서 두번째 for문의 변수?(바뀌는 값. 이걸 변수라고 표현하는 게 맞는지는 모르겠다..)가 j인 것이다.
첫번째 변수는 arr[][i] 0,1,2 이렇게 변하는 i 이다.
이걸 일반화하면 i는 0,1,2...n-1 이렇게 가고 j는 n-1,n-2...1,0 이렇게 가야한다.
따라서
for j in range(n-1,-1,-1):
result +=arr[j][i]
이렇게 된 것이다.
같은 방식으로
case = 180, case 270 일 때에도 이러한 연산을 이용해 1차로 바뀌는 값, 2차로 바뀌는 값을 확인하여 그 식을 구할 수 있다.
이렇게 모범답안을 풀이해보았다.
이젠 내가 모범답안을 보지 않고 직접 코드를 짜볼 차례다.
모범 답안에서는
10
3
1 2 3
4 5 6
7 8 9
을 입력하면(통으로 복사해서 터미널에 붙여넣기 함)
10
#1
3
1 2 3
4 5 6
7 8 9
741 987 369
852 654 258
963 321 147
터미널에 이렇게 표현되었다..(입력값과 출력값이 모두 섞여있는 형태)
근데 난 이게 좀 맘에 안 들었다.
그래서 이걸 좀 보완해서 아래와 같이 코드를 짰다.
- 56,692kb메모리
- 129ms실행시간
T= int(input())
for t in range(1,T+1):
N = int(input())
ang = [90,180,270]
num_lst = []
for n in range(N): #리스트 만들기
num_lst.append(input().split())
for n in range(N): #n번째 줄
if n==0:
print("#{}".format(t))
stng = ""
for a in ang:
if a==90:
for j in range(N-1,-1,-1):
stng+= num_lst[j][n]
stng+=" "
elif a==180:
for j in range(N-1,-1,-1):
stng+= num_lst[N-1-n][j]
stng+=" "
elif a==270:
for j in range(0,N):
stng+= num_lst[j][N-1-n]
print(stng)
모범답안과 전체적인 틀은 비슷하다.
터미널에는 이렇게 나온다.
10
3
1 2 3
4 5 6
7 8 9
#1
741 987 369
852 654 258
963 321 147
#1부터는 출력값이고 그 위에는 입력값이다.
진짜 쉽지 않은 문제였다.
이것저것 복잡한 연산이 정말 머리를 싸매게 만든다.
이런 문제에 익숙해지는 날이 오기를 바란다.
'Python > code problem' 카테고리의 다른 글
[sw expert academy] 1926. 간단한 369 게임 (0) | 2022.01.15 |
---|---|
[sw expert academy] 2005. 파스칼의 삼각형 (0) | 2022.01.12 |
[sw expert academy] 1974. 스도쿠 검증 (0) | 2022.01.07 |
[sw expert academy] 1954. 달팽이 숫자 (0) | 2022.01.06 |
[sw expert academy] 1966. 숫자를 정렬하자 (0) | 2022.01.05 |