알고리즘
백준 - 12906 새로운 하노이 탑, 13414 수강신청
ghtis1798
2021. 8. 4. 08:03
12906 새로운 하노이 탑
12906번: 새로운 하노이 탑
첫째 줄에 막대 A에 놓여져 있는 원판의 개수와 막대 A의 상태, 둘째 줄에 막대 B에 놓여져 있는 원판의 개수와 막대 B의 상태, 셋째 줄에 막대 C에 놓여져 있는 원판의 개수와 막대 C의 상태가 주
www.acmicpc.net
📌문제유형
- set, map
- bfs
- queue
📌자료구조
- q (queue) : 방문할 하노이 탑을 담는 Queue 자료구조
- visited (set) : 이미 방문한 하노이 탑을 담는 Set 자료구조
- count (int) : 이동횟수를 저장하는 변수
📌해결과정
- queue에 각 막대별 처음 원판 상태와 이동횟수를 tuple로 저장한다.
- q가 존재할 동안 다음 loop를 반복한다.
- q를 꺼낸 후 A,B,C 막대 상태를 조합해 방문상태를 의미하는 문자열을 생성한다.
- A막대에는 A만, B막대에는 B만, C막대에는 C만 존재하면 이동횟수 출력 후 종료한다.
- 방문하지 않은 상태라면 아래의 하노이 탑 과정을 수행한다.
- A막대 원판이 존재한다면, A의 마지막 원판을 b로 이동한 경우, c로 이동한 경우를 q에 저장
- B막대 원판이 존재한다면, B의 마지막 원판을 c로 이동한 경우, a로 이동한 경우를 q에 저장
- C막대 원판이 존재한다면, C의 마지막 원판을 b로 이동한 경우, a로 이동한 경우를 q에 저장
from collections import deque
visited = set()
q = deque()
a = input().split()
s1 = a[-1] if len(a)>1 else ''
a = input().split()
s2 = a[-1] if len(a)>1 else ''
a = input().split()
s3 = a[-1] if len(a)>1 else ''
q.append((s1, s2, s3, 0))
while q:
a, b, c, count = q.popleft()
cont_str = a + '/' + b + '/' + c
if a=='A'*len(a) and b=='B'*len(b) and c=='C'*len(c):
print(count)
break
if cont_str not in visited:
visited.add(cont_str)
if len(a)>0:
q.append((a[:-1], b+a[-1], c, count+1))
q.append((a[:-1], b, c+a[-1], count+1))
if len(b)>0:
q.append((a, b[:-1], c+b[-1], count+1))
q.append((a+b[-1], b[:-1], c, count+1))
if len(c)>0:
q.append((a, b+c[-1], c[:-1], count+1))
q.append((a+c[-1], b, c[:-1], count+1))
13414 수강신청
13414번: 수강신청
입력 데이터는 표준 입력을 사용한다. 입력은 1개의 테스트 데이터로 구성된다. 입력의 첫 번째 줄에는 과목의 수강 가능 인원 K(1 ≤ K ≤ 100,000)와 학생들이 버튼을 클릭한 순서를 기록한 대기목
www.acmicpc.net
📌문제유형
- set, map
- 처음에 수강신청 대기열을 떠올리며 Queue로 문제를 해결하려고 시도했다.
- 하지만 시간초과로 통과하지 못했고 그 이유는 다음과 같다.
- 시간제한 1초, 입력 최대길이가 500,000이므로 Queue 연산과정에 소요되는 Overhead가 크다.
📌자료구조
- success (dictionary) (key:학번, value:순서번호): 학번과 순서를 저장한 딕셔너리
- order (int) : 수강신청 순서번호를 의미하는 변수
- cnt (int) : 수강정원을 count하는 변수
📌해결과정
- 수강인원 k, 클릭 대기목록 수 l을 입력받는다.
- 대기목록을 입력 받으며 딕셔너리에 key는 입력받은 학번, value는 순서번호 order를 저장한다.
- 입력이 끝난 후 딕셔너리를 order에 따라 정렬한다.
- 작은 order 순으로 학번을 출력하고, cnt 개수가 수강정원 k에 도달하면 종료한다.
-
import sys import operator k, l = map(int, input().split()) success = dict() order = 1 for _ in range(l): student = sys.stdin.readline().strip() success[student] = order order += 1 success = sorted(success.items(), key = operator.itemgetter(1)) cnt = 0 for key, value in success: if cnt == k: break print(key) cnt+=1