[이코테] #2 구현

yeco_ob·2023년 2월 17일
0
post-thumbnail

구현

구현이란 머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정이다. 대체로 사소한 조건이 많아 코드로 구현하기 까다로우며 문법을 정확히 숙지하지 못했거나 라이브러리 사용이 부족하다면 구현 유형의 문제를 풀 때 불리하다.

✨ C/C++ 사용 시 변수의 표현 범위에 주의
✨ 파이썬은 다른 언어에 비해 복잡함이 적은 편이지만 데이터 처리량이 많을 때는 꼭 메모리 제한을 고려

예제

🔒상하좌우

import sys
input = sys.stdin.readline
#입력값 받기
n = int(input())
move_list = input().split()
x, y = 1, 1 #초기 좌표(1,1)
#방향벡터 정의
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
move_type = ['L', 'R', 'U', 'D']
#좌표 이동 반복문
for i in move_list:
    for j in range(len(move_type)):
        if i == move_type[j]:
            nx = x + dx[j]
            ny = y + dy[j]
            #범위 조건: n넘으면 코드 실행 건너뛰기
            if nx < 1 or nx > n or ny < 1 or ny > n:
                continue
            x, y = nx, ny #좌표 이동

print(x, y)

방향벡터를 이용해

for j in range(len(move_type)):
        if i == move_type[j]:

💡 0부터 move_type의 길이 만큼을 j값이 돌며 반복문을 수행하도록 해주고 i값과 같다면 좌표를 이동한다.

이런 문제는 일련의 명령에 따라서 개체를 차례대로 이동시킨다는 점에서 시뮬레이션유형으로 분류되며 구현이 중요한 대표적인 문제 유형이다.

🔒시각

h = int(input())
cnt = 0

for i in range(h+1): #0~h
    for m in range(60): #0~59
        for s in range(60):
            if '3' in str(i) + str(m) + str(s):
                cnt += 1

print(cnt)

이 문제는 3중 반복문을 돌리면 해결된다.
그리고 조건문으로 3이 포함되면 카운트해주며 결과를 출력한다.

실전 문제

🔒왕실의 나이트

data = input()
cnt = 0
#행과 열로 나누기
row = int(data[1])
column = int(ord(data[0])) - int(ord('a')) + 1
#이동가능한 8가지 방향
move = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
#이동이 가능하다면 카운트
for i in move:
    nRow = row + i[0]
    nColum = column + i[1]
    if nRow <= 8 and nColum <= 8 and nRow >= 1 and nColum >= 1:
        cnt +=1
#출력
print(cnt)

✨ord(): 하나의 문자에 대한 아스키 코드(ASCII Code) 정수 값을 반환

column = int(ord(data[0])) - int(ord('a')) + 1

이 코드는 문자를 아스키 코드 정수 값을 반환받고 인덱스로 사용하기 위해 a의 아스키 코드값을 뺀 후 1을 더해주는 것이다. 본 문제의 인덱스는 1부터 시작하기 때문에 1을 더해줘야 한다.

이전 문제와 다른 성격으로 이동할 방향을 기록했다.
이번 소스코드에선 move 리스트 내에 이동 가능한 8가지 방향을 원소로 넣고 반복문으로 i가 돌며 범위 내라면 카운트한다.

🔒게임 개발

n, m = map(int, input().split())
#리스트컴프리헨션으로 n*m 맵 생성(방문한 곳인지 기록)
d = [[0] * m for _ in range(n)]
x, y, direction = map(int, input().split())
d[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 t_left():
    global direction
    direction -= 1
    if direction == -1: #북쪽이라면
        direction = 3 #서쪽 방향값인 3을 대입

#시뮬레이션 시작
cnt = 1 #초기 위치 포함
turn_cnt = 0
while True:
    t_left() #왼쪽으로 돌기
    nx = x + dx[direction] #바라보는 방향으로 이동
    ny = y + dy[direction]
    # 회전 후 정면에 가지 않은 칸이 있다면
    if d[nx][ny] == 0 and arr[nx][ny] == 0:
        d[nx][ny] = 1 #방문처리
        x = nx #이동
        y = ny
        cnt += 1
        turn_cnt = 0
        continue
    else: #회전 후 정면에 가지 않은 칸이 없거나 바다라면
        turn_cnt += 1
    # 4방향 전부 갈 수 없을 때
    if turn_cnt == 4:
        nx = x - dx[direction]
        ny = y - dy[direction]
        if arr[nx][ny] == 0: #후진이 가능하면 후진
            x = nx
            y = ny
        else: #후진하는 곳이 바다라면 반복문 탈출
            break
        turn_cnt = 0

print(cnt)

차원 좌표, 왼오른쪽으로 기준점의 방향 이동 등 까다로운 조건이 있어 소스코드로 옮기는 과정이 다소 까다로웠다.

문제를 읽으면 보이는 특징

💡왼쪽으로 도는 과정을 자주 사용한다.

그래서 왼쪽으로 도는 t_left 함수를 만들어 주어진 조건에 맞게 북쪽(0)에서 -1을 하면 -1이므로 서쪽(3)의 값인 3을 대입해줘야 한다.

💡방문한 곳은 1로 변경하는 d리스트를 따로 선언했다.

💡네 방향 전부 가본 곳이라는 문제의 조건을 코드로 표현하기 위해 turn_cnt 변수로 4번이 차면(4방향으로 다 돌았음) 다음 동작을 하도록 했다.

💡t_left 함수에서 global 키워드를 사용했는데 direction 정수형 변수가 함수 밖에서 선언된 전역변수이기 때문이다.

코딩도장 전역 변수 👉 변수에 대해 자세한 설명이 있숨다

메모

백준에서 몇몇 구현 문제를 풀었는데 해결책은 쉽게 떠오르지만 코드로 옮기는 게 쉽지,,,아니하다,,, 자주 반복해서 접해야겠음

0개의 댓글