Ch4. 구현 implementation
1. 아이디어를 코드로 바꾸는 구현
1-1. 피지컬로 승부하기
- '코딩 테스트에서 구현이란?'
: 머릿 속에 있는 알고리즘을 소스코드로 바꾸는 과정이다. 모든 범위의 코딩 테스트 문제 유형을 포함하는 개념이다.
그렇기 때문에 대부분 구현을 별도의 유형으로 다루지 않지만, 코딩 테스트에서는 자주 출제가 된다.
- '피지컬이 좋다'
: 프로그래밍 문법을 정확하게 숙지하고, 라이브러리 사용 경험이 풍부하며, 코드 작성 속도(타자)가 빠를 때
- '구현 유형의 문제'
: 풀이를 떠올리는 것은 쉽지만, 소스코드로 옮기기 어려운 문제
(알고리즘은 설계했는데 구현이 먼저 풀 수 있는 문제가 없을 때 푸는 것이 좋다)
1) 완전 탐색: 모든 경우의 수를 주저 없이 다 계산하는 해결 방법
2) 시뮬레이션: 문제에서 제시한 알고리즘을 한 단계씩 차례대로 직접 수행해야하는 문제 유형
1-2. 구현 시 고려해야 할 메모리 제약 사항
- '변수의 표현 범위'
1) C/C++/Java
: int형, long long형, BigInteger 순으로 자료형의 표현 범위에 주의해야한다.
2) Python
: 직접 자료형을 지정할 필요가 없고 매우 큰 수의 연산 또한 지원하므로 주의하지 않아도 된다.
- '파이썬에서 리스트 크기'
: 파이썬에서 리스트를 이용할 때 코딩 테스트의 메모리 제한을 고려해야 한다. (그러나, 드물다)
1-3. 채점 환경
- 시간 제한이 1초이고, 데이터의 개수가 100만개인 문제가 있다면 일반적으로 시간 복잡도 O(NlogN)이내의
알고리즘을 이용하여 풀어야 한다. N = 1,000,000(100만) -> NlogN = 약 20,000,000(2000만번)
(제출한 코드가 1초에 2000만번의 연산을 수행한다고 가정하면 크게 무리가 없다)
- 따라서 알고리즘 문제를 풀 때는 시간 제한과 데이터의 개수를 먼저 확인한 뒤 이 문제를 어느 정도의 시간 복잡도의
알고리즘으로 작성해야 풀 수 있을 것인지 예측할 수 있어야 한다.
1-4. 구현 문제에 접근하는 방법
- 특징
1) 문제의 길이가 길지만, 고차원적인 사고력을 요구하지 않기 때문에 문법에 익숙하다면 오히려 쉽게 풀 수 있다.
2) 문자열을 처리하거나 큰 정수를 처리하는 구현 문제가 나올 때는 C/C++/Java보다 Python이 쉬울 수 있다.
1-5. 상하좌우
- 문제

- 문제 해결
: 요구사항대로 구현하면 연산 횟수는 이동 횟수에 비례하게 된다. 이동 횟수가 N번인 경우 시간 복잡도 O(N)이다.
일련의 명령에 따라 개체를 차례대로 이동시킨다는 점에서 simulation 유형으로 분류되며 구현이 중요한 문제다.
- 소스 코드

1-6. 시각
- 문제

- 문제 해결
: 00시 00분 00초 ~ 23시 59분 59초까지의 모든 경우의 수는 86,400가지(24*60*60초)이다.
경우의 수가 100,000가지도 되지 않기 때문에 시간 제한 2초 안에 문제를 해결할 수 있다.
가능한 경우의 수를 모두 검사하는 방법으로 완전 탐색 유형이다.
일반적으로 탐색해야할 전체 데이터의 개수가 100만개 이하일 때 완전 탐색을 사용하면 적절하다.
- 소스 코드

2. 왕실의 나이트
- 문제


- 문제 해결
: 나이트가 위치한 곳을 문자열과 숫자의 조합이 아니라 같은 행과 열 형태로 들어올 수도 있었다. (예외처리 필요)
이 문제는 나이트가 이동할 수 있는 경로를 하나씩 확인하여 이동하면서 결과를 확인하면 된다.
나이트가 이동할 수 있는 경로는 2가지이다.
1) 수평으로 두 칸 이동 후 수직으로 한 칸 이동
2) 수직으로 두 칸 이동 후 수평으로 한 칸 이동

가능한 움직임을 (x,y) 나타내면 (-1, -2), (1, -2), (-1, 2), (1, 2), (-2, -1), (2, -1), (-2, 1), (2, 1)로 8가지의 경우가 나온다.
상하좌우와 비슷한 문제지만 이동방향을 dx,dy를 사용하느냐,
특정 방향 값을 지정하여 방향을 설정하느냐 2가지 모두 자주 사용되므로 참고!
- 소스 코드

3. 게임 개발
- 문제


- 문제 해결
: 문제가 길고 문제를 바르게 이해하여 소스 코드로 옮기는 과정이 간단하지 않기 때문에 반복적인 숙달이 필요하다.
- 소스 코드
n, m = map(int, input().split())
visit = [[0] * m for _ in range(n)]
x, y, direction = map(int, input().split())
visit[x][y] = 1
arr = []
for i in range(n):
arr.append(list(map(int, input().split())))
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
def turn_left():
global direction
direction -= 1
if direction == -1:
direction = 3
count = 1;
turn_time = 0
while True:
turn_left()
nx = x + dx[direction]
ny = y + dy[direction]
if visit[nx][ny] == 0 and arr[nx][ny] == 0:
visit[nx][ny] = 1
x = nx
y = ny
count += 1
turn_time = 0
continue
else:
turn_time += 1
if turn_time == 4:
nx = x - dx[direction]
ny = y - dy[direction]
if arr[nx][ny] == 0:
x = nx
y = ny
else:
break
turn_time = 0
print(count)
#include <stdio.h>
using namespace std;
int N, M, x, y, dir;
int dx[4] = { -1, 0, 1, 0 };
int dy[4] = { 0, 1, 0, -1 };
int arr[51][51];
int visit[51][51];
void turn_left() {
dir -= 1;
if (dir == -1) dir = 3;
}
int main() {
scanf("%d %d", &N, &M);
scanf("%d %d %d", &x, &y, &dir);
visit[x][y] = 1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++)
scanf("%d", &arr[i][j]);
}
int count = 1;
int turn_cnt = 0;
while (true) {
turn_left();
int nx = x + dx[dir];
int ny = y + dy[dir];
if (visit[nx][ny] == 0 && arr[nx][ny] == 0) {
visit[nx][ny] = 1;
x = nx; y = ny;
count += 1; turn_cnt = 0;
continue;
}
else turn_cnt += 1;
if (turn_cnt == 4) {
nx = x - dx[dir];
ny = y - dy[dir];
if (arr[nx][ny] == 0) {
x = nx; y = ny;
}
else break;
turn_cnt = 0;
}
}
printf("%d", count);
return 0;
}
'Algorithm&Problem > [Algorithm] 이.코.테.다' 카테고리의 다른 글
[7일차] 이.코.테.다! Ch6 정렬 (0) | 2020.10.02 |
---|---|
[6일차] 이.코.테.다! Ch5 DFS/BFS (0) | 2020.09.22 |
[4일차] 이.코.테.다! Ch3 그리디 greedy (0) | 2020.09.16 |
[3일차] 이.코.테.다! Ch2 16~20년 코테 기출 유형 분석 (0) | 2020.09.12 |
[2일차] 이.코.테.다! Ch1 코딩테스트 개요 (0) | 2020.09.11 |