[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)
    

참고 사이트

이코테 구현 강의 영상