반응형

문제 풀이

dp와 dfs를 함께 사용해야하는 문제이다.

1. dp 배열에 해당 칸을 방문한 적이 없으면 -1, 있으면 해당 칸부터 (0,0)까지 갈 수 있는 현재까지 발견한 경로의 수를 담는다.

2. 위의 dp 배열과 지도를 기반으로 dfs를 진행한다.

  2-1) 이동 가능한 칸의 dp값이 -1이라면 방문한다.

  2-2) 이동 가능한 칸의 dp값이 0이라면 방문하지 않는다. 해당 칸에서는 (0,0)까지 갈 수 없다.

  2-3) 이동 가능한 칸의 dp값이 1이상이라면 현재 칸의 dp값에 이동 가능한 칸의 dp값을 더해준다. 현재 칸에서 (0,0)까지 갈 수 있는 방법의 수는, 현재 칸에서 이동할 수 있는 칸들에서부터 (0,0)까지 갈 수 있는 경로의 합이다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import sys
sys.setrecursionlimit(10000)
# 0: 상, 1: 좌, 2: 하, 3: 우
= [0,-1,0,1]
= [-1,0,1,0]
def dfs(x,y):
    if dp[y][x] == -1 : 
        dp[y][x] = 0
    if x<0 or x>n-1 or y<0 or y>m-1return 0
    for i in range(4):
        nx = x + a[i]
        ny = y + b[i]
        if (0 <= nx <= n-1 and 0 <= ny <= m-1and maps[ny][nx] > maps[y][x] :
            if dp[ny][nx] > 0:
                dp[y][x] += dp[ny][nx]
            # 방문한 적 없으면 dfs
            elif dp[ny][nx] == -1 :
                dp[y][x] += dfs(nx,ny)
    return dp[y][x]
        
if __name__ == '__main__':
    m,n = map(int,sys.stdin.readline().split())
    maps = [list(map(int, sys.stdin.readline().split())) for _ in range(m)]
 
    dp = [[-1* n for _ in range(m)]
    dp[0][0= 1
    dfs(n-1,m-1
    print(dp[-1][-1])
 
cs

Line 9 : 지도를 벗어나면 0을 반환한다.

Line 13 : 새로운 좌표가 지도를 벗어나지 않으며 이동가능하면, 새로운 좌표를 dfs하거나(Line 17, 과정 2-2) 현재 칸의 dp 값에 새로운 좌표의 dp값을 더해준다(Line 14, 과정 2-3).

 

문제 링크

 

1520번: 내리막 길

여행을 떠난 세준이는 지도를 하나 구하였다. 이 지도는 아래 그림과 같이 직사각형 모양이며 여러 칸으로 나뉘어져 있다. 한 칸은 한 지점을 나타내는데 각 칸에는 그 지점의 높이가 쓰여 있으�

www.acmicpc.net

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 11057 오르막 수 Python  (0) 2020.12.03
백준 4358 생태학  (0) 2020.10.21
백준 1152 단어의 개수  (0) 2020.08.31
백준 2884 알람 시계  (0) 2020.05.08
백준 9465 스티커  (0) 2020.04.18
반응형

문제 풀이

1. 달팽이는 아래방향, 오른쪽 방향, 대각선(왼쪽 위) 방향 이 세가지를 번갈아 움직입니다.

  - 따라서 방향을 바꿀 때마다 check 변수에 1씩 더해주며, check mod 3이 방향이 됩니다.

2. 편의상 정사각형에서 움직인다고 생각하고 풀었습니다.

3. 아래로 움직일 때의 경우의 수를 생각해보면 다음과 같습니다.

  3-1) 끝까지 왔거나, 아래 방향의 칸이 0이 아닌 경우 : 방향을 오른쪽으로 바꾼 후, 오른쪽으로 한칸 움직인 후, 해당 칸을 현재 값으로 바꿔줍니다..

  3-2) 아래 방향의 칸의 값이 0인 경우 : 아래로 이동 후, 아래 칸의 값을 현재 값으로 바꿔줍니다.

4. 3의 과정을 오른쪽 방향, 대각선 방향에 대해서도 구현해 줍니다.

5. 밑변의 길이가 n일 때, 총 칸의 수 tot(n)은 다음의 재귀식으로 나타낼 수 있습니다.

  tot(n) = tot(n-1) + 1 , tot(1) = 1

  예를 들어, n=2일 때의 칸의 수는 tot(1) + 2 = 3이고, n=3일 때의 칸의 수는 tot(3) = tot(2) + 3 = 6입니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def solution(n):
    direction = ['down','right','diagonal']
    check = 0
    answer = []
    square = [[0 for i in range(n)] for j in range(n)]
    i,j = 0,0
    square[j][i] = 1
    tot = sum(i for i in range(1,n+1))
    for s in range(2,tot+1):
        d = direction[check%3]
        if d == 'down':
            if j+1==or square[j+1][i] != 0:
                check += 1
                square[j][i+1= s
                i += 1
            else:
                square[j+1][i] = s
                j += 1
        elif d == 'right':
            if i+1 == n or square[j][i+1!= 0 :
                check += 1
                square[j-1][i-1= s
                j-=1
                i-=1
            else :
                square[j][i+1= s
                i += 1
        else :
            if square[j-1][i-1!= 0:
                check +=1
                square[j+1][i] = s
                j += 1
            else :
                square[j-1][i-1= s
                j -= 1
                i -= 1
    for i,v in enumerate(square):
        answer += v[:i+1]
    return answer
 
 
cs

 

Line 8 : 과정 5의 재귀식을 표현한 값입니다.

Line 37 : 사각형에서 필요한 부분만 잘라 answer에 붙여줍니다.

문제 링크

 

코딩테스트 연습 - 삼각 달팽이

5 [1,2,12,3,13,11,4,14,15,10,5,6,7,8,9] 6 [1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]

programmers.co.kr

 

반응형
반응형

2019 카카오 개발자 겨울 인턴십 문제

문제풀이

1. move의 앞에서부터 요소 m을 한개 씩 뽑습니다.

2. board에서 (m-1)열에 인형이 있는지 확인하고, 있다면 가장 높이 있는 인형의 높이를 찾습니다.

3. board에서 인형을 뽑았다면 뽑은 위치의 값을 0으로 수정합니다.

4. 인형을 넣을 스택을 선언합니다.

5. 과정 2에서 뽑은 인형을 스택의 탑과 비교한 후, 같으면 둘다 없애고 다르다면 둘다 넣어줍니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from collections import deque
 
def solution(board, moves):
    answer = 0
    q = deque()
    board.insert(0, [0 for i in board[0]])
    for m in moves:
        m -= 1
        y = get_top(board, m)
        # 들어 있으면
        if y:
            doll = board[y][m]
            board[y][m] = 0
            if q:
                tmp = q.pop()
                if doll == tmp:
                    answer += 2
                    continue
                else:
                    q.append(tmp)
                    q.append(doll)
            else:
                q.append(doll)
    return answer
# 들어 있으면, 인형의 높이를 반환
def get_top(board, idx):
    for i, v in enumerate(board):
        if v[idx] != 0:
            return i
    return 0
            
cs

Line 5 : 뽑은 인형을 넣어줄 스택으로, deque 자료구조를 사용했습니다.

Line 8 : moves의 경우 맨 앞이 0이 아닌 1이므로, 편의상 -1을 해줍니다.

Line 26 : 해당 열에 인형이 있다면 가장 높은 인형의 위치를 반환해줍니다.

Line 6 : 인형이 맨 위에 있을 경우, get_top 함수가 0을 반환하여 안들어있다고 인식하는 문제를 개선하기 위해 맨 위에 모든 요소가 0인 리스트를 넣어줬습니다. get_top 함수가 True, False를 같이 반환하도록 한다면 이 과정이 생략될 수 있습니다.

Line 11 : 해당 열에 인형이 들어있는 경우입니다.

Line 14 : 인형을 넣는 스택에 인형이 들어있는 경우입니다.

Line 16 : 스택의 탑과 인형이 같은 경우 입니다. 탑을 다시 넣어주지 않고 넘어갑니다.

Line 19 : 스택의 탑과 인형이 다른 경우, 둘다 다시 넣어줍니다. 탑을 먼저 넣어주어야합니다.

Line 22 : 스택이 비어있는 경우, 인형을 넣어줍니다.

문제 링크

 

코딩테스트 연습 - 크레인 인형뽑기 게임

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

programmers.co.kr

 

반응형
반응형

문제 풀이

1. 이중 포문을 활용해서 모든 가능한 쌍의 합을 answer에 넣어줍니다.

2. set 자료구조를 활용해서 answer에서 중복값을 없애줍니다.

3. 다시 list로 변환 후, 정렬하여 반환합니다.

 

Python Code

1
2
3
4
5
6
def solution(numbers):
    answer = []
    for i,v in enumerate(numbers):
        for j,w in enumerate(numbers[i+1:]):
            answer.append(w+v)
    return sorted(list(set(answer)))
cs

문제 링크

 

코딩테스트 연습 - 두 개 뽑아서 더하기

정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요. 제한�

programmers.co.kr

 

반응형
반응형

문제풀이

1. 키패드에서 숫자의 좌표를 정의합니다. 저는 1이 (0,0), #이 (3,2)로 했습니다.

2. numbers에서 주어진 수를 하나씩 꺼내며 숫자가 1,4,7이면 answer에 L을 더하고 왼손의 좌표를 누른 숫자의 좌표로 바꿔줍니다. 주어진 숫자가 3,6,9이면 answer에 R을 더하고 오른손의 좌표를 바꿔줍니다. 주어진 숫자가 가운데 줄에 있는 수인 경우 왼손으로부터의 거리와 오른손으로부터의 거리를 비교하여 짧은 손을 이용합니다. 거리는 각 손의 좌표와 숫자의 좌표의 x축 값끼리의 차의 절댓값과 y축 값끼리의 차의 절댓값을 더한 값이 됩니다.

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
global dic
dic = {}
dic['0'= [3,1]
dic['*'= [3,0]
dic['#'= [3,2]
= 0
= 0
for n in range(1,10):
    dic[str(n)] = [i,j]
    j+=1
    if j==3:
        i+=1
        j=0
def solution(numbers, hand):
    global dic
    answer = ''
    l = [3,0]
    r = [3,2]
    for n in numbers:
        near = get_nearest_hand(n,l,r)
        if n in [1,4,7]:
            answer += 'L'
            l = dic[str(n)]
        elif n in [3,6,9]:
            answer += 'R'
            r = dic[str(n)]
        else:
            if near == 'l':
                answer += 'L'
                l = dic[str(n)]
            elif near == 'r':
                answer += 'R'
                r = dic[str(n)]
            else:
                if hand =='right':
                    answer +='R'
                    r = dic[str(n)]
                else:
                    answer += 'L'
                    l = dic[str(n)]
                
    return answer
 
def get_nearest_hand(num,l,r):
    global dic
    tmp = dic[str(num)]
    l_dist = abs(l[0- tmp[0]) + abs(l[1- tmp[1])
    r_dist = abs(r[0- tmp[0]) + abs(r[1- tmp[1])
    if l_dist > r_dist:
        return 'r'
    elif l_dist < r_dist:
        return 'l'
    else :
        return 's'
cs

Line 1 : dic은 키가 숫자이고 값이 좌표인 딕셔너리입니다.

Line 44 : 주어진 숫자가 2,5,8,0인 경우, 숫자로부터 더 가까운 거리의 손을 반환하는 함수입니다.

Line 34 : 양손으로부터 거리가 같은 경우, 오른손잡이인지 왼손잡이인지를 고려합니다.

 

문제 링크

programmers.co.kr/learn/courses/30/lessons/67256

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

 

반응형
반응형

2018 KAKAO BLIND RECRUITMENT 문제이다.

 

문제 풀이

1. 먼저 주어진 시간을 시작시간과 종료시간으로 적절히 연산가능하도록 변환해 준다.(저는 datetime 라이브러리를 사용하였습니다.)

2. 각 시작시간과 종료시간마다 1초의 여유를 두고 동시에 진행중인 프로세스의 개수를 센다.

자세한 풀이는 카카오 공식 풀이를 참조하세요.

* 계속 테스트케이스의 한 두개가 틀렸는데, 종료시간에 대해서만 비교를해서 그랬습니다. 시작시간과 종료시간 모두 동시에 수행중인 프로세스의 수가 바뀔 수 있습니다.

* 과정 2 부분을 이중포문으로 구현했으므로 시간복잡도는 O(n^2)이 됩니다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import datetime
from collections import deque
 
def solution(lines):
    answer = 0
    traffics = []
    
    for l in lines:
        date, time, t = l.split()
        tmp_date = list(map(int,date.split("-")))
        tmp_time = time.split(":")
        sec, msec = tmp_time[2].split('.')
        end = datetime.datetime(tmp_date[0],tmp_date[1],tmp_date[2],int(tmp_time[0]),int(tmp_time[1]),int(sec),int(float("0."+msec)*1000000))
        start = end - datetime.timedelta(seconds = float(t[:-1])) + datetime.timedelta(seconds = 0.001)
        
        traffics.append((start,end + datetime.timedelta(seconds = 1)))
    #기준 시간    
    for start, end in traffics:
        count_start = 0
        count_end = 0
        for s,e in traffics:
            if s < start <= e :
                count_start += 1
            if s < end <= e :
                count_end += 1
        if max(count_start,count_end) > answer :
            answer = max(count_start,count_end)
        
    return answer
cs

Line 8 - 16 : 주어진 시간을 datetime 라이브러리를 활용하여 연산 가능하게 변환하고 traffics 리스트에 넣어줍니다.

Line 18 - 27 : 첫 for문의 start와 end가 기준시간으로 해당 시간의 1초 여유 안에 있는 traffics의 요소의 개수를 세어줍니다.

 

문제 링크

 

코딩테스트 연습 - [1차] 추석 트래픽

입력: [ 2016-09-15 20:59:57.421 0.351s, 2016-09-15 20:59:58.233 1.181s, 2016-09-15 20:59:58.299 0.8s, 2016-09-15 20:59:58.688 1.041s, 2016-09-15 20:59:59.591 1.412s, 2016-09-15 21:00:00.464 1.466s, 2016-09-15 21:00:00.741 1.581s, 2016-09-15 21:00:00.748

programmers.co.kr

 

반응형
반응형

문제 풀이

1. 공백을 기준으로 단어를 잘라 단어의 개수를 출력하는 문제이다.

2. 앞 뒤에 공백이 있는 경우가 있으므로 strip() 함수로 앞뒤 공백을 제거해준다.

3. ' ' 가 입력으로 들어오는 경우를 고려해주어야한다.

Python Code

1
2
temp = input().strip()
print(len(temp.split(' ')) if len(temp) > 0 else 0)
cs

문제 링크

 

1152번: 단어의 개수

첫 줄에 영어 대소문자와 띄어쓰기로 이루어진 문자열이 주어진다. 이 문자열의 길이는 1,000,000을 넘지 않는다. 단어는 띄어쓰기 한 개로 구분되며, 공백이 연속해서 나오는 경우는 없다. 또한 �

www.acmicpc.net

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 4358 생태학  (0) 2020.10.21
백준 1520 내리막 길  (0) 2020.10.20
백준 2884 알람 시계  (0) 2020.05.08
백준 9465 스티커  (0) 2020.04.18
백준 11657 타임머신 / 벨만 포드 알고리즘  (0) 2020.04.11
반응형

문제풀이

 들어온 동물의 ID 중 ANIMAL_OUTS 에 없는 ID 중 DATETIME이 가장 작은 동물 3마리의 이름과 들어온 날짜를 출력한다.

Oracle Code

1
2
3
4
5
6
7
8
9
SELECT Z.NAME, Z.DATETIME
FROM (SELECT NAME, DATETIME
    FROM ANIMAL_INS X
    WHERE NOT EXISTS (
        SELECT 1
        FROM ANIMAL_OUTS Y
        WHERE X.ANIMAL_ID = Y.ANIMAL_ID)
    ORDER BY X.DATETIME) Z
WHERE ROWNUM<=3
cs

문제 링크

 

코딩테스트 연습 - 오랜 기간 보호한 동물(1)

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디

programmers.co.kr

 

반응형

+ Recent posts