구현
머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정이다.
이코테 책에서는 완전 탐색, 시뮬레이션 유형을 모두 구현 유형으로 묶어 다룬다.
- 완전 탐색: 모든 경우의 수를 주저 없이 다 계산하는 해결 방법
- 시뮬레이션: 문제에서 제시한 알고리즘을 한 단계씩 차례대로 직접 수행하는 것
예제 1 : 상하좌우
문제
여행가 A는 N × N 크기의 정사각형 공간 위에 서 있다. 이 공간은 1 × 1 크기의 정사각형으로 나누어져 있다.
가장 왼쪽 위 좌표는 (1, 1)이며, 가장 오른쪽 아래 좌표는 (N, N)에 해당한다.
여행가 A는 상, 하, 좌, 우 방향으로 이동할 수 있으며, 시작 좌표는 항상 (1, 1)이다. 우리 앞에는 여행가 A가
이동할 계획이 적힌 계획서가 놓여 있다
계획서에는 하나의 줄에 띄어쓰기를 기준으로 L, R, U, D 중 하나의 문자가 반복적으로 적혀있다.
각 문자의 의미는 다음과 같다
- L: 왼쪽으로 한 칸 이동
- R: 오른쪽으로 한 칸 이동
- U: 위로 한 칸 이동
- D: 아래로 한 칸 이동
이때 여행가 A가 N × N 크기의 정사각형 공간을 벗어나는 움직임은 무시된다
예를 들어 (1, 1)의 위치에서 L 혹은 U를 만나면 무시된다
다음은 N = 5인 지도와 계획이다
입력
첫째 줄에 공간의 크기를 나타내는 N이 주어집니다. (1<=N<=100)
둘째 줄에 여행가 A가 이동할 계획서 내용이 주어집니다. (1<=이동 횟수<=100)
출력
첫째 줄에 게임의 룰에 맞게 선택한 카드에 적힌 숫자를 출력
입력 예시
5
R R R U D D
출력 예시
3 4

2차원 배열 행렬에 쌩쇼를 하고 있었는데.. 심플했던 문제였다..ㅠㅠ
이 문제는 일련의 명령에 따라 개체를 이동시킨다는 점에서 시뮬레이션 유형으로 분류된다!
💡 시작 위치를 지정해서 L/R/U/D case별로 액션 지정
n = int(input())
arr = list(map(str,input().split()))
now = [1,1] // 시작 위치 지정
for i in arr:
if i=='L':
if now[1]>1:
now[1]-=1
elif i=='R':
if now[1]<n:
now[1]+=1
elif i=='U':
if now[0]>1:
now[0]-=1
elif i=='D':
if now[1]<n:
now[0]+=1
print(now[0],now[1])
💡 책 풀이
n = int(input())
x, y = 1, 1
plans = input.split()
# L, R, U, D에 따른 이동 방향
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
move_types = ['L', 'R', 'U', 'D']
# 이동 계획을 하나씩 확인
for plan in plans:
# 이동 후 좌표 구하기
for i in range(len(move_types)):
if plan == move_types[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
print(x,y)
예제 2 : 시각
문제
정수 N이 입력되면 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는
모든 경우의 수를 구하는 프로그램을 작성하라. 예를 들어 1을 입력했을 때
다음은 3이 하나라도 포함되어 있으므로 세어야 하는 시각이다
- 00시 00분 03초
- 00시 13분 30초
반면에 다음은 3이 하나도 포함되어 있지 않으므로 세면 안 되는 시각이다
- 00시 02분 55초
- 01시 27분 45초
입력
첫째 줄에 정수 N이 입력된다.(0<=N<=23)
출력
00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 출력한다.
입력 예시
5
출력 예시
11475
💡 완전 탐색으로 풀기
시각을 1씩 증가시키면서 3이 하나라도 포함되어 있는지 확인한다.
전체 시, 분, 초에 대한 경우의 수는 24*60*60이며 3중 반복문을 이용해 계산한다.
예) 03시 20분 35초 확인하려면 => '032035'로 만들어 3이 포함되었는지 확인한다.
h = int(input())
count = 0
for i in range(h+1):
for j in range(60):
for k in rnage(60):
# 매 시각 안에 3이 포함되어 있다면 카운트 증가
if '3' in str(i) + str(j) + str(k):
count += 1
print(count)
예제 3 : 왕실의 나이트
문제
이처럼 8 × 8 좌표 평면상에서 나이트의 위치가 주어졌을 때 나이트가 이동할 수 있는 경우의 수를 출력하는
프로그램을 작성하라. 왕실의 정원에서 행 위치를 표현할 때는 1부터 8로 표현하며, 열 위치를 표현할 때는
a 부터 h로 표현한다
- c2에 있을 때 이동할 수 있는 경우의 수는 6가지이다
- a1에 있을 때 이동할 수 있는 경우의 수는 2가지이다
입력
첫째 줄에 8x8 좌표 평면상에서 현재 나이트가 위치한 곳의 좌표를 나타내는 두 문자로 구성된 문자열이 입력된다. 입력 문자는 a1 처럼 열과 행으로 이뤄진다.
출력
첫째 줄에 나이트가 이동할 수 있는 경우의 수를 출력하시오.
입력 예시
a1
출력 예시
2
💡 예제 1처럼 이동 액션을 미리 다 정의해놓고 이동시킨다.
💡 column에는 문자를 입력으로 받기 때문에 정수로 바꾸는 작업이 필요하다.
column = int(ord(input_data[0])) - int(ord('a')) + 1 하는 이유?
➡️ a의 아스키 코드값(97)을 기준으로 얼마나 떨어져 있는지 계산하여 1부터 8까지의 열로 매핑하기 위해서!
예를 들어, input_data[0]가 'a'라면 ord(input_data[0])는 97이 되고,
따라서 int(ord(input_data[0])) - int(ord('a')) + 1은 97 - 97 + 1로 1이 됨. 'a' 열이 체스 판 상의 1열을 나타내기 때문
- ord 함수: 하나의 문자를 인자로 받고 해당 문자에 해당하는 유니코드 정수를 반환
ex) ord('a')를 넣으면 정수 97을 반환
- chr 함수: 정수를 인자로 받고 해당 정수에 해당하는 유니코드 문자를 반환
input_data = input()
row = int(input_data[1])
column = int(ord(input_data[0])) - int(ord('a')) + 1
# 나이트가 이동할 수 있는 8가지 방향 정의
steps = [(-2,-1),(-1,-2),(1,-2),(2,-1),(2,1),(1,2),(-1,2),(-2,1)]
# 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인
result = 0
for step in steps:
# 이동하고자 하는 위치 확인
next_row = row+step[0]
next_cloumn = column+step[1]
# 해당 위치로 이동이 가능하다면 카운트 증가
if next_row>=1 and next_row<=8 and next_column>=1 and next_column<=8:
result += 1
print(result)
예제 4 : 문자열 재정렬
문제
알파벳 대문자와 숫자(0~9)로만 구성된 문자열이 입력으로 주어집니다. 이때 모든 알파벳을 오름차순으로 정렬하여 이어서 출력한 뒤에, 그 뒤에 모든 숫자를 더한 값을 이어서 출력합니다.
예를 들어 K1KA5CB7이라는 값이 들어오면 ABCKK13을 출력합니다.
입력
하나의 문자열 S가 주어집니다. ( 1<= S의 길이 <= 10,000)
출력
문제에서 요구하는 정답을 출력합니다.
💡리스트에 저장된 알파벳을 정렬해 출력하고, 합계를 뒤에 붙여 출력하면 정답이다.
💡isalpha()를 통해 알파벳의 경우를 뽑아낸다!
data = input()
result = []
value = 0
# 문자를 하나씩 확인하며
for x in data:
# 알파벳인 경우 결과 리스트에 삽입
if x.isalpha():
result.append(x)
# 숫자는 따로 더하기
else:
value += int(x)
# 알파벳을 오름차순으로 정렬
result.sort()
# 숫자가 하나라도 존재하는 경우 가장 뒤에 삽입
if value != 0:
result.append(str(value))
# 최종 결과 출력(리스트를 문자열로 변환하여 출력)
print(''.join(result))
백준 2979
문제
상근이는 트럭을 총 세 대 가지고 있다. 오늘은 트럭을 주차하는데 비용이 얼마나 필요한지 알아보려고 한다.
상근이가 이용하는 주차장은 주차하는 트럭의 수에 따라서 주차 요금을 할인해 준다.
트럭을 한 대 주차할 때는 1분에 한 대당 A원을 내야 한다. 두 대를 주차할 때는 1분에 한 대당 B원, 세 대를 주차할 때는 1분에 한 대당 C원을 내야 한다.
A, B, C가 주어지고, 상근이의 트럭이 주차장에 주차된 시간이 주어졌을 때, 주차 요금으로 얼마를 내야 하는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 문제에서 설명한 주차 요금 A, B, C가 주어진다. (1 ≤ C ≤ B ≤ A ≤ 100)
다음 세 개 줄에는 두 정수가 주어진다. 이 정수는 상근이가 가지고 있는 트럭이 주차장에 도착한 시간과 주차장에서 떠난 시간이다. 도착한 시간은 항상 떠난 시간보다 앞선다. 입력으로 주어지는 시간은 1과 100사이 이다.
출력
첫째 줄에 상근이가 내야하는 주차 요금을 출력한다.
💡 트럭 세 대의 도착시간과 떠난 시간을 리스트에 담는다.
💡 떠난 시간 세 개를 max함수로 비교해 가장 마지막으로 떠난 트럭의 시간을 구해 해당 크기의 리스트 parking을 만들어 모두 0으로 초기화한다.
if __name__ == "__main__":
one_fee, two_fee, three_fee = map(int, input().split())
table = [list(map(int, input().split())) for _ in range(3)]
maxtime = max(table[0][1], table[1][1], table[2][1])
parking = [0] * (maxtime - 1)
for car in table:
for i in range(car[0] - 1, car[1] - 1):
parking[i] += 1
fee = 0
for i in parking:
if i == 1:
fee += one_fee
elif i == 2:
fee += 2 * two_fee
elif i == 3:
fee += 3 * three_fee
print(fee)
'Coding Test' 카테고리의 다른 글
[TIL/10.23] Algorithm: DFS/BFS (0) | 2023.10.22 |
---|---|
[TIL/10.21] Algorithm: 자료구조 기초와 DFS/BFS (0) | 2023.10.22 |
[TIL/10.19] Algorithm: 그리디 알고리즘 (0) | 2023.10.19 |
[TIL/10.14] 백준 - 2차원 배열 골라풀기 (0) | 2023.10.14 |
[TIL/10.14] 백준 기초- 1차원 배열 (0) | 2023.10.14 |