[Algorithm] 구현
Intro
그리디 다음으로 구현 챕터이다. 항상 어떻게 풀지에 대한 아이디어는 떠오르지만 아이디어를 코드로 구현하는 과정이 굉장히 어려웠다. 이 챕터에서는 구현하는 과정을 경험하는 과정들을 거친다.
구현 알고리즘
구현이란, “머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정”으로 정의한다.
- 구현 문제들은 머릿속에서 풀이가 떠올라도 해당 프로그래밍 언어로 정확히 구현해야 정답 처리를 받을 수 있다.
- 그렇기에, 해당 프로그래밍 언어의 문법과 요구사항을 꼼꼼하게 체크하여 코드를 실수 없이 작성해야 정답 처리를 받을 수 있다.
- 구현 문제들은 대부분 문제의 길이가 길다. 그렇기에 당황하지 말고 천천히 요구사항을 체크한 후 문법과 라이브러리를 잘 활용해야 한다.
- 또한 시간 제한 및 데이터의 개수를 확인한 후 시간 복잡도를 고려하여 문제를 풀이해야 한다.
- 이코테 책에서는 완전탐색, 시뮬레이션을 모두 ‘구현’으로 묶어서 다룬다.
예제1. 상하좌우
여행가 A는 NXN 크기의 정사각형 공간 위에 서 있습니다. 이 공간은 1X1 크기의 정사각형으로 나누어져 있습니다. 가장 왼쪽 위 좌표는 (1,1)이며, 가장 오른쪽 아래 좌표는 (N,N)에 해당합니다. 여행가 A는 상,하,좌,우 방향으로 이동할 수 있으며, 시작 좌표는 항상 (1,1)입니다. 우리 앞에는 여행가 A가 이동할 계획이 적힌 계획서가 놓여 있습니다.
계획서에는 하나의 줄에 띄어쓰기를 기준으로 하여 L,R,U,D 중 하나의 문자가 반복적으로 적혀있습니다. 각 문자의 의미는 다음과 같습니다. L: 왼쪽으로 한 칸 이동 R: 오른쪽으로 한 칸 이동 U: 위로 한 칸 이동 D: 아래로 한 칸 이동 이때, 여행가 A가 NXN 크기의 정사각형 공간을 벗어나는 움직임은 무시됩니다.
-입력 첫째 줄에 정수 N이 입력된다.(0<=N<=23) -출력 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 출력한다. -입력 예시 5 -출력 예시 11475
- 해결 방법(아이디어)
- 정수를 입력받아 계획서를 입력받는다.
- LRUD에 대한 이동방향을 리스트로 선언한다.
- move_type을 선언한다.
- 계획서를 통해 좌표를 임시변수에 이동한 후 범위를 벗어나는 지 여부를 확인한 후 벗어나지 않았을 경우 x, y값을 출력한다.
- 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# 1. 공간 크기 n = int(input()) # 2. 계획서 내용 plans = input().split() # L R U D dx = [0, 0, 1, -1] dy = [-1, 1, 0, 0] move_type = ['L', 'R', 'U', 'D'] start, end = 1 ,1 # 계획을 하나씩 확인 for plan in plans: # 이동 후 좌표 확인 for i in range(len(move_type)): if plan == move_type[i]: nx = x + dx[i] ny = y + dy[i] if nx < 1 or ny < 1 or nx > n or ny > n: continue x, y = nx, ny
예제2. 시각
정수 N이 입력되면 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 구하는 프로그램을 작성하세요. 예를 들어 1을 입력했을 때 다음은 3이 하나라도 포함되어 있으므로 세어야 하는 시각입니다. 00시 00분 03초 00시 13분 30초
- 해결방법(아이디어)
- 3중 반복문을 사용한다.
- 시, 분, 초를 모두 탐색하여 해결함.
- 코드
1 2 3 4 5 6 7 8 9 10
N = int(input("정수를 입력하시오")) minutes = 60 second = 60 cnt = 0 for n in range(0, N+1): for i in range(minutes): for j in range(second): if '3' in str(n) or '3' in str(i) or '3' in str(j): cnt += 1 print(cnt)
예제3. 왕실의 나이트
행복 왕국의 왕실 정원은 체스판과 같은 8 × 8 좌표 평면이다. 왕실 정원의 특정한 한 칸에 나이트가 서있다. 나이트는 매우 충성스러운 신하로서 매일 무술을 연마한다 나이트는 말을 타고 있기 때문에 이동을 할 때는 L자 형태로만 이동할 수 있으며 정원 밖으로는 나갈 수 없다 나이트는 특정 위치에서 다음과 같은 2가지 경우로 이동할 수 있다
1. 수평으로 두 칸 이동한 뒤에 수직으로 한 칸 이동하기
2. 수직으로 두 칸 이동한 뒤에 수평으로 한 칸 이동하기
이처럼 8 × 8 좌표 평면상에서 나이트의 위치가 주어졌을 때 나이트가 이동할 수 있는 경우의 수를 출력하는 프로그램을 작성하라. 왕실의 정원에서 행 위치를 표현할 때는 1부터 8로 표현하며, 열 위치를 표현할 때는 a 부터 h로 표현한다.
c2에 있을 때 이동할 수 있는 경우의 수는 6가지이다 a1에 있을 때 이동할 수 있는 경우의 수는 2가지이다 -입력 첫째 줄에 8x8 좌표 평면상에서 현재 나이트가 위치한 곳의 좌표를 나타내는 두 문자로 구성된 문자열이 입력된다. 입력 문자는 a1 처럼 열과 행으로 이뤄진다. -출력 첫째 줄에 나이트가 이동할 수 있는 경우의 수를 출력하시오. -입력 예시 a1 -출력 예시 2
- 해결방법(아이디어)
- 이동할 수 있는 방법 2가지를 변수에 저장한다.
- 현재 위치에서 이동 방법을 통해 이동한 후 범위 내에 있는 지 확인하고 범위에 있는 경우에만 값을 증가하여 처리.
- 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
cnt = 0 # 현재 위치 입력 받기(행, 열) # - 행은 숫자, 열은 알파벳 night = input() x, y = night[1], ord(night[0]) # print(x,y) limit_x, limit_y = 8, ord('h') # 이동 방법 step = [(2,1), (2,-1), (-2,1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)] # 이동 for i,j in step: # print(i,j) # 범위를 벗어날 경우 if int(x) + i > limit_x or int(x) + i <= 0 or int(y) + j > limit_y or int(y) + j <= 0: continue else: cnt += 1 print(cnt)