Sad Puppy 3 '코딩테스트/문제 풀이 - Python' 카테고리의 글 목록 :: 개발자 아지트

[정답코드]

from collections import deque
import copy
def solution(name):
    answer = float("inf")
    name = list(name)
    
    origin=['A']*len(name)
    
    now = 0
    
    controll=0
    controll+=min(ord(name[now])-ord('A'), ord('Z')-ord(name[now])+1)#min(ord(name[now])-65, 90-ord(name[now])+1)
    
    origin[now]=name[now]
    q=deque([])
    q.append((now, controll, origin))
    while q:
        now, controll, origin =q.popleft()
        if origin == name:
            answer=min(answer, controll)
            continue

        check=0
        rcontroll = controll
        rnow=now
        while check<1:
            # 오른쪽으로 가는 경우, 
            rnow=rnow+1
            if rnow>=len(name):
                rnow=0
            # 값을 바꿀 필요가 있는 경우 
            if origin[rnow]!=name[rnow]:
                if 0<=rnow<len(name):
                    check=1
                    rcontroll+=min(ord(name[rnow])-65, 90-ord(name[rnow])+1)+1

                    break
                    #q.append((nnow, controll+1, origin))
            # 값을 바꿀 필요가 없는 경우 
            else:
                rcontroll+=1

        check = 0
        lcontroll = controll
        lnow=now
        while check<1:
            # 왼쪽으로 가는 경우,     
            lnow = lnow -1
            if lnow<0:
                lnow=len(name)-1
            # 값을 바꿀 필요가 있는 경우
            if origin[lnow]!=name[lnow]:
                if 0<=lnow<len(name) :
                    check = 1  
                    lcontroll+=min(ord(name[lnow])-65, 90-ord(name[lnow])+1)+1
                    break
            else:
                lcontroll+=1

        originl=origin[:]
        originr=origin[:]
        originl[lnow]=name[lnow]
        q.append((lnow, lcontroll, originl))
        originr[rnow]=name[rnow]
        q.append((rnow, rcontroll, originr))
            
    
    return answer

 

 

일단 이 문제는 그리디 문제이긴 한데, 그리디 하지 않다. 

 

from collections import deque
import copy
def solution(name):
    answer = float("inf")
    name = list(name)
    origin=['A']*len(name)
    now = 0
    controll=0
    controll+=min(ord(name[now])-65, 90-ord(name[now])+1)
    origin[now]=name[now]
    q=deque([])
    q.append((now, controll, origin))
    while q:
        # print('!', now, controll, origin)
        now, controll, origin =q.popleft()
        
        if origin == name:
            
            answer=min(answer, controll)
            #print('answer', answer)
            continue

        check=0
        rcontroll = controll
        rnow=now
        while check<1:
            # 오른쪽으로 가는 경우, 
            rnow=rnow+1
            if rnow>=len(name):
                rnow=0
            
            # 값을 바꿀 필요가 있는 경우 
            if origin[rnow]!=name[rnow]:
                if 0<=rnow<len(name):
                    check=1
                    # print('now controll', controll, 'plus', min(ord(name[nnow])-65, 90-ord(name[nnow])))
                    rcontroll+=min(ord(name[rnow])-65, 90-ord(name[rnow])+1)+1
                    #origin[rnow]=name[rnow]
                    break
                    #q.append((nnow, controll+1, origin))
            # 값을 바꿀 필요가 없는 경우 
            else:
                rcontroll+=1

        check = 0
        lcontroll = controll
        lnow=now
        # print('lnow1',lnow)
        while check<1:
            # 왼쪽으로 가는 경우,     
            lnow = lnow -1
            if lnow<0:
                lnow=len(name)-1
            # 값을 바꿀 필요가 있는 경우
            if origin[lnow]!=name[lnow]:
                if 0<=lnow<len(name) :
                    check = 1
                    # print('now controll', controll, 'plus', min(ord(name[nnow])-65, 90-ord(name[nnow])))
                    lcontroll+=min(ord(name[lnow])-65, 90-ord(name[lnow])+1)+1
                    #origin[lnow]=name[lnow]
                    break
                    #q.append((nnow, controll+1, origin))
            else:
                lcontroll+=1
        # print('lnow2',lnow)
        #print('lcontroll, rcontroll:', lcontroll-controll, rcontroll-controll, ',', lcontroll, rcontroll,'controll', controll)      
        if lcontroll<rcontroll:
            #print('hi', origin)
            origin[lnow]=name[lnow]
            #print('hi2', origin, 'lcontroll',lcontroll)
            q.append((lnow, lcontroll, copy.deepcopy(origin)))
        elif lcontroll>rcontroll:
            #print('hi', origin)
            origin[rnow]=name[rnow]
            
            #print('hi2', origin, 'lcontroll',lcontroll)
            q.append((rnow, rcontroll, copy.deepcopy(origin)))
        else:
            originl=copy.deepcopy(origin)
            originr=copy.deepcopy(origin)
            originl[lnow]=name[lnow]
            q.append((lnow, lcontroll, copy.deepcopy(originl)))
            originr[rnow]=name[rnow]
            q.append((rnow, rcontroll, copy.deepcopy(originr)))
            
        
    # print(controll)
    
    
    return answer

 

 

이렇게 작성한 코드에서

이런식으로 도저히 넘어가질 않았음.

그런데 내가 하루종일 찾은 테스트케이스는 모두 통과되는 상태임.

 

이건 진짜 근본적인 문제가 하나 있다 싶었다. 

 

내가 이 문제를 풀기위해 사용한 핵심 로직은 

 

"지금 당장 더 싼 쪽(왼쪽 vs. 오른쪽)만 골라서 다른 쪽은 아예 버린다"
(만약 두쪽 다 값이 같으면 둘다 살려줌)

 

이였고, 오히려 그리디한 그리디 분기(pruning) 로직임.



그런데 이게 문제를 해결할 수 없는 결정적인 오류였음. 

이렇게 하면, 현재 상황에서 비용이 더 큰 쪽 경로를 전혀 탐색하지 않는데, 이 경우에서 만약 나중에 더 긴 A 구간이 나와버리면,  “한 번에 건너뛰어서” 전체 이동 횟수를 줄여 줄 수도 있는 상황을 전부 잘라 버림. 

결과적으로, 단편적인 부분에서 싸 보인다고 더 비싼 쪽 경로를 잘라 버리는 순간, 전역 최적해를 놓치게 되는거임;

 

결국 더 싼쪽 골라서 q에 넣기보다는 아예 저 조건 싹 지워버렸음


폭포수 시원하게 흐르는 것 같노

 

 

 

느낀점 : 그리디 문제도 깊게 생각할 부분이 있구나 하는것을 알게되었음.

https://www.acmicpc.net/problem/11279

 

문제 해결 방법

파이썬에서는 힙 자료구조를 heapq 를 통해 제공한다. 이때 최소힙 기능만 사용할 수 있고, 최대힙 기능은 지원하지 않는다. 

최소값일 수록 우선순위를 가지고 맨 앞에 배치되니, 최대 힙을 사용하고 싶으면 값들을 넣을 때 -를 붙여 넣고, 출력할때는 -를 달아서 출력하면 최대힙 처럼 사용할 수 있다. 

 

코드 구현

 

정답 코드 

'''
# 최대 힙
'''
import heapq
import sys
input = sys.stdin.readline
n = int(input())

tmp = []
for i in range(n):
    value = int(input())
    if value !=0:
        heapq.heappush(tmp, -value)
    else:
        if not tmp:
            print(0)
        else:
            print(-heapq.heappop(tmp))

 

 

시간/공간 복잡도

log(n)

 

어려웠던 점

 

알게된 점

  • heapq 모듈 사용방법 

https://www.acmicpc.net/problem/14503

 

문제 해결 방법

이 문제는 문제 설명에 올라와있는대로 그대로 풀면 된다. 

 

  1. 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
  2. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 없는 경우,
    1. 바라보는 방향을 유지한 채로 한 칸 후진할 수 있다면 한 칸 후진하고 1번으로 돌아간다.
    2. 바라보는 방향의 뒤쪽 칸이 벽이라 후진할 수 없다면 작동을 멈춘다.
  3. 현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 있는 경우,
    1. 반시계 방향으로 90도 회전한다.
    2. 바라보는 방향을 기준으로 앞쪽 칸이 청소되지 않은 빈 칸인 경우 한 칸 전진한다.
    3. 1번으로 돌아간다.

 

다만 문제는 반시계 방향으로 90도씩 회전을 해야한다는 것이고, 

현재 칸의 주변 4칸 중 청소되지 않은 빈 칸이 발견되는 즉시!! 반시계 방향으로 90도 회전해야한다. 

 

코드 구현

 

정답 코드 

 

import sys
from collections import deque

input = sys.stdin.readline
n, m = map(int, input().split())
startY, startX, dir = map(int, input().split())
mapp = []
for i in range(n):
    mapp.append(list(map(int, input().split())))

dx=[0, -1, 0, 1] # 북 서 남 동
dy=[-1, 0, 1, 0] # 북쪽을 y, x 기준 1, 0으로 표기해서 틀렸음 ....... 정신차려!! 

def solutions(x, y, dir):
    cnt = 0 # 청소하는 칸의 개수 
    while 1:
        # 현재 칸이 아직 청소되지 않은 경우, 현재 칸을 청소한다.
        if mapp[y][x] == 0:
            mapp[y][x]=9
            cnt+=1

        check = 0 # 주변 4칸이 모두 청소된 칸인지 확인용 1은 청소필요, 1은 청소 불필요 
        for i in range(4):
            nx=x+dx[i]
            ny=y+dy[i]
        
            if mapp[ny][nx]==0:
                #청소 필요한 칸 발견
                check =1
                break
            
        if check == 1:
            # 반시계 방향으로 90도 회전
            dir=dir+1
            if dir==4:
                dir = 0
            sx=x+dx[dir]
            sy=y+dy[dir]
            
            if mapp[sy][sx]==0:
                # 전진함 
                x = sx
                y = sy
        
        # 청소가 필요 없는 경우 
        if check ==0:
            nny = y-dy[dir]
            nnx = x-dx[dir]
            
            if mapp[nny][nnx]==1:
                return cnt
            else:
                x=nnx
                y=nny

if dir ==1:
    dir = 3
elif dir ==2:
    dir =2
elif dir == 3:
    dir = 1
print(solutions(startX, startY, dir))

 

 

시간/공간 복잡도

시뮬레이션 문제라 고려하지 않았다. 

 

어려웠던 점

  • 반시계 반향으로 회전하려면, 문제에서 제시한 방향 기준으로 델타 x, y의 배열을 미리 선언할 때 조심해야 한다. 
  • 우측 상단 방향이 행, 열 값이 증가하는 상황이라면  북쪽 방향으로 가는것이 (1, 0)이겠지만 해당 문제의 경우, 우측 하단으로 가야 행, 열이 값이 증가하는 상황이다. 이런 경우 북쪽으로 가는 것은 (-1, 0)이다.

 

알게된 점

  • 좌표 문제의 경우, 쪽이 행과 열을 증가시키는 쪽인지 잘 확인하고 이를 고려하여 문제를 풀어야한다. 
  • 델타 x, y좌표 배열을 선언할 때도, 문제에서 관련 조건이나 방법을 제시하는지 잘 확인하여 선언해야 한다. 

https://www.acmicpc.net/problem/1620

문제 해결 방법

 

딕셔너리를 잘 활용하여 문제를 해결한다. 

 

코드 구현

정답 코드 

import sys
input = sys.stdin.readline

n, m = map(int, input().split())
dic = {}
revDic = {}
for i in range(n):
    tmpS = input().strip()
    dic[i+1]=tmpS
    revDic[tmpS]=i+1

for i in range(m):
    tmpV = input().strip()
    if tmpV.isdigit():
        tmpV= int(tmpV)
        print(dic[tmpV])
    else:
        print(revDic[tmpV])

 

시간/공간 복잡도

O(n)

 

어려웠던 점

  • 자료구조 조회할 때, 시간초과를 해결하기 위해서는 리스트보다 해시테이블을 구조인 딕셔너리 사용(O(1)) 이 더 빠르기 때문에 효과적이다.  

알게된 점

  • 키 값을 통해 값을 찾거나 밸류 값을 통해 값을 찾아야 하는 경우, 두개의 딕셔너리를 활용하면 아주 효율적이다. 
  • 문자열이 숫자 값인지 확인할때, 대상.isdigit()함수를 사용하면 확인할 수 있다. (숫자일 경우 True 반환)

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준11279] 최대 힙  (0) 2024.10.02
[백준14503] 로봇 청소기  (1) 2024.10.01
[백준1003] 피보나치 함수  (0) 2024.09.09
[백준11723] 집합  (0) 2024.09.09
[백준1012] 유기농 배추  (0) 2024.09.09

https://www.acmicpc.net/problem/1003

 

문제 해결 방법

재귀함수 혹은 DP를 활용한다. 

코드 구현

정답 코드 

import sys
input = sys.stdin.readline
t = int(input())


def fibonacci(n, count):
    if n<=1:
        if n ==0:
            count[0]+=1
        if n==1:
            count[1]+=1

        print(count[0], count[1])
        return n
    
    a = 0
    b = 1

    for i in range(2, n+1):
        c = a + b
        a = b
        b = c


    print(a, b)
    return b 
        

for i in range(t):
    n = int(input())
    count = [0, 0]
    fibonacci(n, count)

# 0 1 1 2 3 5 8

 

시간/공간 복잡도

O(n)

 

최적화 및 개선

  • 피보나치 함수 알고리즘을 구현할 때, 재귀함수로 구현후 시간 초과가 나면 DP로 구현하면 시간 복잡도를 줄일 수 있다. 

 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준14503] 로봇 청소기  (1) 2024.10.01
[백준1620] 나는야 포켓몬 마스터 이다솜  (0) 2024.09.09
[백준11723] 집합  (0) 2024.09.09
[백준1012] 유기농 배추  (0) 2024.09.09
[백준1926] 그림  (0) 2024.08.26

https://www.acmicpc.net/problem/11723

문제 해결 방법

리스트를 잘 활용하여 문제를 해결한다. 

 

코드 구현

정답 코드 

 

import sys
input = sys.stdin.readline

n = int(input())
tmp = []
for i in range(n):
    entire = input().strip()
    if entire=='all': 
        tmp = list(range(1, 21))
    elif entire=='empty':
        tmp.clear()
    else:
        s, v = entire.split()
        v = int(v)
        if s == 'add':
            if v not in tmp:
                tmp.append(v)
        
        if s == 'check':
            if int(v) in tmp:
                print(1)
            else:
                print(0)
        
        if s == 'remove':
            if v in tmp:
                tmp.remove(v)
        
        if s == 'toggle':
            if int(v) in tmp:
                tmp.remove(v)
            else:
                tmp.append(v)

 

시간/공간 복잡도

O(n)

 

어려웠던 점

  • 입력값의 타입에 대해 잘 고려하지 않아서 조건문이 제대로 실행되지 않았던 점
  • sys모듈에서 input()함수를 사용할 때, 개행문자(/n)가 붙어서 조건문이 제대로 실행되지 않았던 점

 

느낀점

  • sys모듈에서 input()함수를 사용할 때, 개행문자(/n)를 꼭 처리하여 문제를 해결해야겠다. 
  • 변수 타입에 대해 잘 고려하고 문제를 풀어야겠다. 
  • 리스트를 비우기 위해 대상.cleare() 함수를 사용하면 된다. 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준1620] 나는야 포켓몬 마스터 이다솜  (0) 2024.09.09
[백준1003] 피보나치 함수  (0) 2024.09.09
[백준1012] 유기농 배추  (0) 2024.09.09
[백준1926] 그림  (0) 2024.08.26
[백준9252] LCS 2  (0) 2024.08.14

https://www.acmicpc.net/problem/1012

 

문제 해결 방법

 

배추가 심긴 위치를 순회한다. 방문여부를 알 수 있는 visited 배열이 필요하다. 

좌표를 순회할때 1을 만나고, 방문한 적이 없으면 bfs함수를 실행한다. 

이때, deque를 활용해 큐를 만들고 큐에 bfs함수를 실행할 당시의 좌표값을 넣어준다. 이때 지렁이의 개수를 +1 한다 

bfs함수에서는 큐에서 값을 꺼내어 방문처리를 해주고, 자신의 자리에서 심겨진배추가 이어져 있다는 판단 기준인 위, 아래, 양옆을 조회 한다. 이때, 새로 조회하는 위치가 그림 정보가 적힌 좌표의 범위를 벗어나서도 안되고, 이미 방문 한 적이 있어도 안된다. 또한 0이여도 안된다. 값이 0이 아니고 방문한 적이 없으면 현재자리의 방문체크를 해준다.  

 

그림 정보 순회가 모두 끝나면 임의의 리스트의 원소의 개수와 원소의 최대값을 출력한다. 

 

코드 구현

정답 코드 

import sys
from collections import deque
input=sys.stdin.readline

dx= [0, 0, 1, -1]
dy= [1, -1, 0, 0]

answer=[]
def bfs(y, x):
        queue = deque()
        visited[y][x] = True
        queue.append([y, x])

        while queue:
            ny, nx = queue.popleft()
            for ii in range(4):
                yy= ny+dy[ii]
                xx= nx+dx[ii]

                if 0<=yy<n and 0<=xx<m and mapp[yy][xx]==1 and  visited[yy][xx] == False:
                    visited[yy][xx] = True
                    queue.append([yy, xx])

t = int(input())
for j in range(t):
    m, n, k = map(int, input().split())
    mapp = [[0] * m for _ in range(n)]
    visited = [[False] * m for _ in range(n)]
    cnt = 0
    for i in range(k):
        wm, wn = map(int, input().split())
        mapp[wn][wm] = 1
    
    for ix in range(n):
        for jx in range(m):
            if mapp[ix][jx]==1 and visited[ix][jx] == False:
                    cnt+=1
                    bfs(ix, jx)
    answer.append(cnt)

for i in answer:
  print(i)

 

시간/공간 복잡도

따로 생각하지 않았다. 

 

최적화 및 개선

  • 따로 하지않음

 

어려웠던 점

  • BFS는 큐에 넣기 전에 방문처리를 해야 중복 방문처리를 하지 않게 된다는 것을 알게됐다. 

 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준1003] 피보나치 함수  (0) 2024.09.09
[백준11723] 집합  (0) 2024.09.09
[백준1926] 그림  (0) 2024.08.26
[백준9252] LCS 2  (0) 2024.08.14
[백준17829] 222-풀링  (0) 2024.08.14

https://www.acmicpc.net/problem/1926

 

문제 해결 방법

 

그림 정보가 적힌 좌표를 순회한다. 대신 방문여부를 알 수 있는 visited 배열이 필요하다. 

좌표를 순회할때 1을 만나고, 방문한 적이 없으면 bfs함수를 실행한다. 

이때, deque를 활용해 큐를 만들고 큐에 bfs함수를 실행할 당시의 좌표값을 넣어준다. 

bfs함수에서는 큐에서 값을 꺼내어 방문처리를 해주고, 자신의 자리에서 그림이 이어져 있다는 판단 기준인 위, 아래, 양옆을 조회 한다. 

이때, 새로 조회하는 위치가 그림 정보가 적힌 좌표의 범위를 벗어나서도 안되고, 이미 방문 한 적이 있어도 안된다. 또한 0이여도 안된다. 

값이 0이 아니고 방문한 적이 없으면 현재자리의 값에서+1을 해준다.  큐에 해당 좌표와 얼마나 끊기지 않고 값을 조회하고있는지에 대한 값 현재 자리의 값+1을 넣어준다. 

 

순회를 하면서 더이상 큐에 값을 이어 넣을 수 없으면(그림이 끊기면), 얼마나 끊기지 않고 값을 조회했는지에 대한 값을 임의의 리스트에 넣어준다. 

 

그림 정보 순회가 모두 끝나면 임의의 리스트의 원소의 개수와 원소의 최대값을 출력한다. 

 

코드 구현

정답 코드 

import sys
input=sys.stdin.readline
n, m = map(int, input().split())
from collections import deque

if n==0 and m==0:
    print(0)
    print(0)
    exit(0)

dy=[1, -1, 0, 0]
dx=[0, 0, 1, -1]

tmp=[]
for i in range(n):
    tmp2=list(map(int, input().split()))
    tmp.append(tmp2)

# 그냥 카운트만 하는애 cnt
# 방문 확인용 visited
cnt = 0
visited = [([False] * m) for _ in range(n)]
bigN = 0
def bfs(cnt, dequeA, visited):
    bigN=1
    while dequeA:
        yy, xx, _ = dequeA.popleft()
        visited[yy][xx] = True
        for i in range(4): 
            nx=xx+dx[i]
            ny=yy+dy[i]

            if ny<0 or nx<0 or ny>=n or nx>=m:
                continue
            if visited[ny][nx]==True or tmp[ny][nx]==0:
                continue
            if tmp[ny][nx]>=1 and visited[ny][nx]==False:
                tmp[ny][nx] = bigN+1
                bigN=bigN+1
                visited[ny][nx]=True
                dequeA.append([ny,nx, bigN])
    return cnt, bigN

tmp3=[]
check = 0
dequeA = deque()
for i in range(n):
    for j in range(m):
        if tmp[i][j] == 1 and visited[i][j] == False:
            dequeA.append([i,j, 1])
            cnt+=1
            cnt, bigN = bfs(cnt, dequeA, visited)
            tmp3.append(bigN)
            check =1

print(cnt)

if n == 0 and m ==0 or check ==0:
    print(0)
else:
    print(max(tmp3))

 

시간/공간 복잡도

따로 생각하지 않았다. 

 

최적화 및 개선

  • 따로 하지않음

 

어려웠던 점

  • BFS 문제를 효율적으로 푸는 방법이 가물가물해서 문제 풀기 어려웠다. 

 

알게된 것

 

함수 객체 할당과 함수 호출 구문을 구분하지 못해서 생긴 일 

 

여러줄을 받을 때 속도 감소를 위해 input()함수 말고 sys 에서 제공하는 readline()함수를 사용하려는 상황이다. 

import sys

n, m = map(int, input().split())

input=sys.stdin.readline()

tmp=[]
for i in range(n):
    
    # tmp2=list(input.split())
    tmp2=input.split()
    print('tmp2', tmp2)
    tmp.append(tmp2)

print(tmp)

 

문제가 있는 코드: 이코드에서는 2번째줄 3번째줄만 입력을 받는게 된다. 

 

  • 괄호를 붙이지 않은 경우 (input = sys.stdin.readline):
    • 이 경우 sys.stdin.readline 함수 객체를 input이라는 변수에 직접 할당하는 것이다. 이 상태에서는 input은 함수 객체 자체를 참조하게 된다.
  • 괄호를 붙인 경우 (input()):
    • 괄호를 붙이면 함수가 실제로 호출된다. 함수 호출은 해당 함수가 수행하는 작업을 실행하고, 그 결과를 반환한다. 

 

import sys

n, m = map(int, input().split())

input=sys.stdin.readline

tmp=[]
for i in range(n):
    
    tmp2=input().split()
    tmp.append(tmp2)

print(tmp)


문제 인지후 바꾼 코드 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준11723] 집합  (0) 2024.09.09
[백준1012] 유기농 배추  (0) 2024.09.09
[백준9252] LCS 2  (0) 2024.08.14
[백준17829] 222-풀링  (0) 2024.08.14
[백준2504] 괄호의 값  (0) 2024.08.12

https://www.acmicpc.net/problem/9252

 

 

 

문제 해결 방법

1. dp배열을 만들어서 lcs를 구함

2. lcs를 구한 dp배열을 역추적하여 문자열을 구함 

 

코드 구현

정답 코드 

 

s1 = input()
s2 = input()

m=len(s1)
n=len(s2)

dp = [[0] * (n+1) for _ in range(m+1)]

for i in range(1, m+1):
    for j in range(1, n+1):
        if s1[i-1]==s2[j-1]:
            dp[i][j]=dp[i-1][j-1]+1
        else:
            dp[i][j]=max(dp[i][j-1], dp[i-1][j])

result =''
startm = m
startn = n

print(max(dp[-1]))
if max(dp[-1])!=0:
    while 1:
            if dp[startm][startn]==0:
                break
            # 위에것이 더 큰지
            if dp[startm][startn] == dp[startm-1][startn]:
                startm-=1
            # 왼쪽 것이 더 큰지
            elif dp[startm][startn] == dp[startm][startn-1]:
                startn-=1
            # 둘다 안크면 대각선 이동 
            # 값도 넣어줌 
            elif ((dp[startm][startn]-1) == dp[startm-1][startn-1]):
                
                startm-=1
                startn-=1

                result+=s2[startn]


            
            

    print(result[::-1])

 

시간/공간 복잡도

0.1초로 시간제한이 있었는데, 해당 시간에 1000만 번의 연산을 해야하는거고, 최대로 입력할 수 있는 문자열의 길이가 1000이기 때문에 

O(n)으로 푸는것이 맞다. 

 

최적화 및 개선

따로 하지 않음 

 

어려웠던 점

lcs의 개념, lcs의 역추적의 개념을 잘 몰라서 접근하기 어려웠다. 

역추적 부분은 아직도 어렵게 느껴진다. 비슷한 문제를 여러번 풀어봐야 할 것 같다. 

 

 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준1012] 유기농 배추  (0) 2024.09.09
[백준1926] 그림  (0) 2024.08.26
[백준17829] 222-풀링  (0) 2024.08.14
[백준2504] 괄호의 값  (0) 2024.08.12
[백준10799] 쇠막대기  (0) 2024.08.09

https://www.acmicpc.net/problem/17829

 

 

문제 해결 방법

1. 맵은 행과 열이 항상 2의 배수일 수 밖에 없다는 것을 인지한다. 

2. 따라서 0행0열 0행 2열 0행 4열... 2행 0열 2행 2열.... 이렇게 맵의 크기만큼 조회한다. 

2-1. 출발지 기준 이때 오른쪽으로 한칸, 아래로 한칸, 아래 오른쪽으로 한칸 을 리스트에 넣는다. 

2-2. 리스트에서 두번재로 큰 수만 모아서 또다른 리스트를 만든다. 

 

2번을 맵의 원소가 1개 남을때 까지 반복하다보면 결과 값이 나온다. 

 

 

코드 구현

정답 코드 

import sys

n = int(input())
block=[]
for i in range(n):
    tmp = list(map(int, sys.stdin.readline().strip().split()))
    block.append(tmp)

while 1:
    if len(block[0])==1:
        print(block[0][0])
        break

    makeBlock = [item[:] for item in block]

    block = []
    for i in range(0, len(makeBlock),2):
        tmp=[]
        for j in range(0, len(makeBlock[0]),2):
            realT=[makeBlock[i][j], makeBlock[i][j+1], makeBlock[i+1][j], makeBlock[i+1][j+1]]
            realT.sort(reverse=True)
            tmp.append(realT[1])

        block.append(tmp)

 

시간/공간 복잡도

해당 문제는 구현문제이기 때문에 시간/공간 복잡도를 따지지 않는다. 

 

최적화 및 개선

따로 하지 않음

 

어려웠던 점

쉬운 구문을 까먹어서 검색해서 찾아봤다 아예 그 구문은 외워야겠다. 

리스트 복사하는 구문과 sort함수 사용법.

 

 

'코딩테스트 > 문제 풀이 - Python' 카테고리의 다른 글

[백준1926] 그림  (0) 2024.08.26
[백준9252] LCS 2  (0) 2024.08.14
[백준2504] 괄호의 값  (0) 2024.08.12
[백준10799] 쇠막대기  (0) 2024.08.09
[백준2110] 공유기 설치  (0) 2024.08.06

+ Recent posts