출처
https://swexpertacademy.com/main/code/problem/problemDetail.do |
문제
각 변에 다음과 같이 16진수 숫자(0~F)가 적혀 있는 보물상자가 있다.
보물 상자의 뚜껑은 시계방향으로 돌릴 수 있고, 한 번 돌릴 때마다 숫자가 시계방향으로 한 칸씩 회전한다.
각 변에는 동일한 개수의 숫자가 있고, 시계방향 순으로 높은 자리 숫자에 해당하며 하나의 수를 나타낸다.
예를 들어 [Fig.1]의 수는 1A3, B54, 8F9, D66이고, [Fig.2]의 수는 61A, 3B5, 48F, 9D6이다.
보물상자에는 자물쇠가 걸려있는데, 이 자물쇠의 비밀번호는 보물 상자에 적힌 숫자로 만들 수 있는 모든 수 중, K번째로 큰 수를 10진 수로 만든 수이다.
N개의 숫자가 입력으로 주어졌을 때, 보물상자의 비밀 번호를 출력하는 프로그램을 만들어보자.
(서로 다른 회전 횟수에서 동일한 수가 중복으로 생성될 수 있다. 크기 순서를 셀 때 같은 수를 중복으로 세지 않도록 주의한다.)
[제약 사항]
- N은 4의 배수이고, 8이상 28이하의 정수이다. (8 ≤ N ≤ 28)
- N개의 숫자는 각각 0이상 F이하로 주어진다. (A~F는 알파벳 대문자로만 주어진다.)
- K는 생성 가능한 수의 개수보다 크게 주어지지 않는다.
[예제]
아래와 같이 (1, B, 3, B, 3, B, 8, 1, F, 7, 5, E) 12개의 숫자가 주어지고 K가 10인 경우를 살펴보자.
이 경우에 생성 가능한 수는 각 회전 별로 다음과 같다.
0회전 : 1B3, B3B, 81F, 75E
1회전 : E1B, 3B3, B81, F75
2회전 : 5E1, B3B, 3B8, 1F7
3회전 : 0회전과 동일
생성 가능한 수를 내림 차순으로 나열하면 다음과 같고, K(=10)번째로 큰 수는 503(=1F7)이다.
(B3B를 중복으로 세지 않도록 주의한다.)
F75, E1B, B81, B3B, 81F, 75E, 5E1, 3B8, 3B3, 1F7, 1B3
[입력]
가장 첫 줄에는 테스트 케이스의 개수 T가 주어지고, 그 아래로 각 테스트 케이스가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 숫자의 개수 N과 크기 순서 K가 주어 진다.
그 다음 줄에는 16진수 0~F 숫자가 공백 없이 N개 주어진다.
[출력]
출력의 각 줄은 '#t'로 시작하고, 공백을 한 칸 둔 다음 정답을 출력한다.
(t는 테스트 케이스의 번호를 의미하며 1부터 시작한다.)
5 // 테스트 케이스의 개수 T = 5 12 10 // 1번째 테스트 케이스, N=12, K=10 1B3B3B81F75E // N개의 숫자 16 2 // 2번째 테스트 케이스, N=16, K=2 F53586D76286B2D8 // N개의 숫자 … // 이하 sample_input.txt 참조 |
#1 503 #2 55541 #3 334454 #4 5667473 #5 182189737 |
풀이
뭔가 특별한 알고리즘을 써서 풀었다고 생각은 안들었다. 그냥 단순히 하라는대로 구현만 하니 풀리는 문제였다.
유의해야 할점을 꼽아보자면
- 사각형 한 변에 할당되는 번호의 개수 == 회전 수라는 점
- 한 번 회전 할 때마다 번호의 끝자리가 맨 앞으로 오게 되는데 한 변에 할당된 개수만큼 회전하면 번호 배치가 동일해지게 되므로 더 회전을 할 이유가 없어진다.
- 중복이 존재하면 안된다. 중복을 없앨 방법으로서 중복을 허용하지 않는 자료구조인 set을 사용하였다.
- 16진수를 10진수로 변환하는 게 관건이었는데 int함수가 진법 변환이 가능하다는 것을 알게 되었다!
- int(x, base=10) 라는 구조로 되어있으며 10진수로 변환시키고 싶은 숫자를 "반드시" string으로 처리해 x 에 넣고 base에 진수를 넣어 사용함.
int형 진법 변환 예시
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
T = int(input())
for t in range(T):
N, K = map(int,input().split())
pw = list(map(str,input()))
cnt = N // 4 # 한 변당 번호 개수 = rotate수
arr = [] # 회전 시킨 후 16진수 번호가 저장 될 리스트
for i in range(cnt): # rotate 수 만큼 회전시킴
pop = pw.pop() #리스트 끝 부분을 맨 앞으로 이동 시키면 한번 회전 완료됨
pw.insert(0,pop)
for j in range(0,N,cnt): # 리스트 내에서 각각 떨어져있는 요소를 하나의 번호로 합침
a = ''
for k in range(j,j+cnt):
a += pw[k]
arr.append(a)
new_arr = set(arr) # 중복을 허용치 않는 자료구조 set 활용
answer = [] # 10진수로 변환된 숫자가 들어갈 리스트
for num in new_arr: # 16진수 -> 10 진수로 변환
answer.append(int(num,16))
sorted_answer = sorted(answer,reverse=True) #내림차순 정렬
print('#{} {}'.format(t+1,sorted_answer[K-1]))
|
'코딩 테스트 > SW 아카데미' 카테고리의 다른 글
[모의 SW 역량 테스트] 1953 탈주범 검거 (Python) (0) | 2020.03.03 |
---|---|
[SWEA] D4 1861 정사각형방 (Python) (0) | 2020.03.03 |
[모의 SW 역량 테스트] 1952 수영장 (Python) (0) | 2020.02.28 |
[모의 SW 역량테스트] 4008 숫자 만들기 (Python) (1) | 2020.02.28 |
[SWEA] D4 1258 행렬찾기 (Python) (0) | 2020.02.27 |