노트/알고리즘

구현

작성

『이것이 코딩 테스트다』 4장 구현 문제다. 상하좌우부터 게임 개발까지는 2차원 좌표에서 방향 배열 dx, dy 로 움직이는 연습이고, 뒤의 네 문제는 기업 코딩 테스트 기출이다. 같은 문제를 세 번 풀었다. 장 폴더의 풀이, 『이것이』 폴더에서 다시 푼 것, 복습용 폴더의 풀이 순서로 둔다. 자물쇠와 열쇠의 복습 풀이와 뱀 문제는 입력을 받는 부분까지만 적고 끝내지 못했다. 게임 개발의 첫 풀이에는 ny = y = dy[direction] 이라는 오타가 있어서 그대로는 돌지 않는다.

상하좌우

처음 풀이

n = int(input())
plans = input().split()

moves = ['L','R','U','D']
# dx=[-1,1,0,0]
# dy=[0,0,-1,1]
# x가 열의 값이 바뀌니까, 좌상단 좌표 배치에서 오른쪽 대각선 으로 갈수록(y++,x++)임
dx=[0,0,-1,1]
dy=[-1,1,0,0]
x=y=1

# for move in moves:
# 인덱스 순서에 따라 dx, dy 결정되니까 인덱스로받아야함
for plan in plans:
    for i in range(len(moves)):
        if plan == moves[i]:
            nx = x + dx[i]
            ny = y + dy[i]
            if nx < 1 or ny < 1 or nx > n or ny > n:
                continue
            else:
                x,y=nx,ny
                # x = nx
                # y = ny
                # 코드 간략화

print(nx,ny)

다시 풀기

n = int(input())
plans = input().split()
moves = ['L','R','U','D']
dx = [0,0,-1,1]
dy = [-1,1,0,0]
x=y=1

for plan in plans:
    for i in range(len(moves)):
        if moves[i] == plan:
            nx = x + dx[i]
            ny = y + dy[i]
            if nx > n or ny > n or nx < 1 or ny < 1:
                continue
            else:
                x,y=nx,ny
print(x,y)

시각

처음 풀이

a = int(input())
count = 0

# for h in range(a): 문제를 정확히 읽어보면 a+1까지 계산해야함
for h in range(a+1):
    for m in range(60):
        for s in range(60):
            # if '3'in str(h+m+s): int로 더해진 다음에 문자열이 됌
            if '3' in str(h)+str(m)+str(s):
                count +=1
print(count)

다시 풀기

n = int(input())
count = 0

for hh in range(n+1):
    for mm in range(60):
        for ss in range(60):
            clock = str(hh)+str(mm)+str(ss)
            if '3' in clock:
                count +=1

print(count)

왕실의 나이트

처음 풀이

a =input()
column=ord(a[0])-ord('a')
row=int(a[1])
moves=[(-2,-1),(-2,1),(2,-1),(2,1),(-1,2),(1,2),(-1,-2),(1,-2)]
count = 0

for move in moves:
    next_row=row+move[0]
    next_column=column+move[1]
    if next_row<1 or next_row>8 or next_column<1 or next_column>8:
        continue
    else:
        count+=1

print(count)

다시 풀기

s=list(input())
moves=[(1,2),(-1,2),(1,-2),(-1,-2),(2,1),(-2,1),(2,-1),(-2,-1)]
x = ord(s[0]) - ord('a') + 1
y = int(s[1])

count = 0

for i in range(len(moves)):
    nx = x + moves[i][1]
    ny = y + moves[i][0]
    if nx > 8 or ny > 8 or nx < 1 or ny < 1:
        continue
    else:
        count+=1

print(count)

게임 개발

처음 풀이. 책을 따라 치며 감을 잡은 것이다

#따라치며 감잡기
n,m = map(int,input().split())

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]

#dx,dy의 인덱스를 담당
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 d[nx][ny]==0 and arr[nx][ny]==0 :
        d[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)

다시 풀기

n,m = map(int,input().split())
x,y,direction = map(int,input().split())
plan = [list(map(int,input())) for _ in range(m)]
d = [[0] * n for _ in range(m)]

dx = [-1,0,1,0]
dy = [0,1,0,-1]
x=y=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 plan[nx][ny] == 0 and d[nx][ny] == 0:
        d[nx][ny] = 1
        x,y=nx,ny
        count +=1
        turn_time = 0
        continue
    else:
        turn_time +=1
    if turn_time ==4:
        nx = x - dx[direction]
        ny = y - dy[direction]
        if plan[nx][ny]==0:
            x,y=nx,ny
        else:
            break
        turn_time = 0
print(count)

럭키 스트레이트

처음 풀이

n=list(map(int,input()))

left=sum(n[:int(len(n)/2)])
right=sum(n[int(len(n)/2):])

if left ==right:
    print("LUCKY")
else:
    print("READY")


#/ gives a floating point result. If you want an integer result, use //.
# left=sum(n[:len(n)/2]) 이 부분에서
# len(n)/2 가 3.0이 나오면서 슬라이싱이 안됐음.

다시 풀기

n = list(map(int,input()))
half = len(n)//2

n1 = n[:half]
n2 = n[half:]

print("LUCKY" if sum(n1) == sum(n2) else "READY")

복습

n=list(map(int,input()))

left = []
right = []

# 0~n//2-1 n//2~n-1
for i in range(len(n)):
    if i < len(n)//2:
        left.append(n[i])
    else:
        right.append(n[i])

print('LUCKY' if sum(left) == sum(right) else 'READY')

문자열 재정렬

처음 풀이

s=list(input())
num_array=['1','2','3','4','5','6','7','8','9']

num=[i for i in s if i in num_array]
string=[i for i in s if i not in num_array]

num=sum(list(map(int,num)))
string.sort()
print(''.join(string),num,sep='')

#배열의 모든 요소를 합쳐 하나의 문자열을 반환합니다.
# print(''.join(list))
# 새로운리스트를 만들어서 출력했구나 과거의 나...

다시 풀기

s=sorted(list(input()))
num = ['1','2','3','4','5','6','7','8','9','0']

idx = 0
for i in s:
    if i not in num:
        break
    idx +=1

s_num = list(map(int,s[:idx]))
s_let = s[idx:]

sum_num = str(sum(s_num))
s_let.append(sum_num)

print(''.join(s_let))

복습

s=list(input())
print(s)
num_li = ['0','1','2','3','4','5','6','7','8','9']
result = 0

for item in s:
    if item in num_li:
        print(item)
        result += int(item)
        #s.remove(item)  -> 여기서 바로 지우면 인덱스가 하나 땡겨져서 아래와 같은 예시일 때
        # 4가지워지면 1이 카운트 안되고 2로 바로 넘어감
        # AJKDSLSI412K4JSJ9D

s.sort()
for item in s:
    print(item,end='')
print(result,end='')

문자열 압축

처음 풀이. 1차는 72점이었고 2차는 해설을 참고했다

# 문자열 1개 부터, len(s)/2 까지 탐색해서, 최소의 result를 찾는다
# 1차 풀이(72점)
def zipper(s,chunk):
    s=list(s)
    temp = ''.join(s[:chunk])
    answer = len(s)
    toggle = 0
    for i in range(chunk,len(s),chunk):
        #chunk가 1이라고 생각
        #chunk 수 만큼 반복해서 붙여주기

        # 문자열 단위 마다 비교 연산
        target = s[i]
        for j in range(1,chunk):
            try:
                target += s[i+j]
            except:
                break
        if temp == target:
            if toggle ==1: # 두 번 연속 압축됐다. -chunk
                answer -= chunk
            else:
                answer = answer - chunk + 1 # 한 번 압축됐다. -chunk +1
            toggle = 1
        else:
            toggle = 0
        temp = target
    return answer


def solution(s):
    answer = len(s)

    for chunk in range(1,int(len(s)/2)+1):
        answer = min(answer,zipper(s,chunk))
    return answer


#2차 풀이 해설 참고

def solution(s):
    answer = len(s)
    for step in range(1,len(s)//2+1):
        compressed = ""
        prev = s[0:step]
        count  = 1
        for next in range(step, len(s), step):
            if prev == s[next:next+step]:
                count+=1
            else:
                compressed += str(count) + prev if count >= 2 else prev
                prev = s[next:next+step]
                count = 1
        compressed += str(count) + prev if count >= 2 else prev
        answer = min(answer,len(compressed))
    return answer

다시 풀기

def solution(s):
    answer =[]

    print(len(s))
    for step in range(1,len(s)//2+1):
        prev = s[:step]
        compressed=''
        num = 1

        for i in range(step,len(s)+1,step):
            if prev == s[i:step+i]:
                num +=1
            # 전 압축문자와 같지 않을 때
            else:
                if num != 1:
                    compressed += str(num) + prev
                else:
                    compressed += prev
                prev = s[i:step+i]
                num = 1
            # step에 짤려 마지막 인덱스가 붙여지지 않을 떄
            if i==len(s)-step and prev[-1] != s[-1]:
                compressed += s[step+i:]

        print(compressed)
        answer.append(len(list(compressed)))

    answer = min(answer)
    return answer

복습

def solution(s):
    answer=len(s)
    for step in range(1,len(s)//2+1):
        compressed=""
        count=1
        prev=s[0:step]
        for next in range(step,len(s),step):
            if prev == s[next:next+step]:
                count+=1
            else:
                compressed += str(count) + prev if count >=2 else prev
                count = 1
                prev=s[next:next+step]
        compressed += str(count) + prev if count >=2 else prev # 뭉텅이 2개 밖에 없을 때 for문 다 돌리고 압축 결과 넣어야 하므로
        answer = min(len(compressed),answer)
    return answer

print(solution('abcabcdede'))

자물쇠와 열쇠

처음 풀이

def rotate_a_matrix_by_90_degree(a):
    n = len(a)
    m = len(a[0])
    result = [[0]*n for _ in range(m)]
    for i in range(n):
        for j in range(m):
            result[j][n-i-1] = a[i][j]
    return result

def solution(key,lock):
    n = len(lock)
    m = len(key)
    #굳이 3배로 하는 이유가 있나?
    #꼬투리 까지 확인하기 위해 양옆이 하나 더 늘어난 3배 체택
    new_lock = [[0]*(n*3)for _ in range(n*3)]
    for i in range(n):
        for j in range(n):
            new_lock[i+n][j+n] = lock[i][j]

    #4가지 방향에 대해서 확인
    for rotation in range(4):
        key = rotate_a_matrix_by_90_degree(key)
        for x in range(n*2):
            # n*2의 이유: 0은 첫 번째 박스의 첫번째 칸, n은 두번째 박스으 첫번째칸, 2n은 세번째 칸의 첫번째칸
            for y in range(n*2):
                # 자물쇠 열쇠 넣기
                # i,j만큼 더함으로써 key를 넣었다고 가정
                for i in range(m):
                    for j in range(m):
                        new_lock[x+i][y+j] += key[i][j]
                if check(new_lock) == True:
                    return True
                #자물쇠 다시 빼기
                for i in range(m):
                    for j in range(m):
                        new_lock[x+i][y+j] -= key[i][j]
    return False

def check(new_lock):
    lock_length = len(new_lock)//3
    #자물쇠 중간 부분 모두 1인지 확인
    for i in range(lock_length,lock_length*2):
        for j in range(lock_length, lock_length*2):
            if new_lock[i][j] != 1:
                return False
    return True

복습. 자물쇠를 3배로 늘리는 데까지 적고 멈췄다

# 행과 열을 바꾸고, 배열의 요소를 회전 값으로 넣기
def rotate_a_matrix_by90_degree(a):
    n = len(a)
    m = len(a[0])
    result = [[0]*n for _ in range(m)]
    for i in range(n):
        for j in range(m):
            result[j][n-i-1] = a[i][j]
    return result

# 자물쇠를 3배로 늘렸다고 가정하고, 가운데만 모두 1인지 확인하는 함수
def check(new_lock):
    lock_length = len(new_lock) // 3
    for i in range(lock_length,lock_length*2):
        for j in range(lock_length,lock_length*2):
            if new_lock[i][j] != 1:
                return False
    return True

def solution(key,lock):
    n=len(lock)
    m=len(key)
    # 영역을 벗어나 열쇠를 넣을 수도 있어서, 아싸리 3배를 늘림.
    # 열쇠크기는 자물쇠보다 같거나 작으니깐 상하좌우 다 보려면 상하좌우3배크기해야 전부 다 볼 수 있음
    new_lock = [[0] *(n*3) for _ in range (n*3)]

뱀 (입력만 받고 멈춤)

# 수도코드 기반의 코드로 작성해보자

# 보드의 크기
n = int(input())

# 사과의 개수
k = int(input())

# 사과의 위치
li_app=[]
for _ in range(k):
    li_app.append(list(map(int,input().split())))

# 방향 변환횟수
l = int(input())

#방향 변환 정보
li_di = []
for _ in range(l):
    li_di.append(input().split())

direction = []