Algorithm

백준 2161, 2902, 9012

김디니 2022. 8. 1. 22:33

2161 카드 1

from collections import deque

n = int(input())
nums = deque(list(range(1, n + 1)))

while len(nums) > 1:
    print(nums.popleft(), end=" ")
    nums.append(nums.popleft())


print(nums[0])

 

1부터 입력값 n까지 범위의 수열을 nums에 리스트 형식으로 담아준다.  추후에 리스트의 왼쪽으로 값을 빼 deque로 담아낸다. 

 

while문으로 nums 값의 개수가 1보다 클 때 까지 반복한다. nums 값의 개수가 1개라면 while문은 종료된다. 

.popleft()로 nums[0] 값을 빼주고, 빼준 값은 출력한다. 

 

빼준 후의 리스트에서 nums[0]의 값을 nums의 맨 뒤로 보내주기 위해

.popleft()의 값을 다시 .append()하여 nums[-1]의 위치로 넣어준다. (append는 리스트의 맨 뒤에 값을 추가하는 것을 이용한다)

 

nums에 값이 1개 남았을 때 while문은 종료되고, 

남은 nums의 값을 출력하여 남게 되는 카드의 번호를 마지막에 출력하도록 한다. 

 

2902 KMP는 왜 KMP일까?

name = input()
temp = []

for i in name.split('-'):
    temp.append(i[0])

print(''.join(temp))

'-'가 포함된 연속된 이름이 입력값이 된다. (Knuth-Morris-Pratt)

이름의 첫 글자를 저장할 리스트 형태의 temp 변수를 만든다. 

 

for문으로 반복하여 '-'를 기준으로 단어를 쪼개어 i에 값을 넘겨준다. 

i 값의 맨 첫 글자를 temp에 넣어준다. 

 

temp에 넣어준 첫 글자들은 ['K', 'M', 'P']와 같이 저장되어 있기 때문에 

.join을 이용하여 연속된 문자열로 출력하도록 한다. 

 

9012 괄호

# 구글링 코드

n = int(input())                        # 반복 횟수 입력값

for i in range(n):                      # n만큼 반복
    stack = []                          # 임시적으로 담아줄 리스트 (소괄호가 완성되면 삭제)
    line = input()                      # 소괄호 입력값
    for item in line:                   # 입력값을 하나씩 변수 item에 옮긴다
        if stack:                       # 무조건 소괄호 하나를 stack 리스트에 넣는다
            if item =='(':              
            
                stack.append(item)      # '('를 stack에 넣는다
                
            elif item==')':             # ')' 라면
                if stack[-1]=='(':      # 마지막에 넣은 값이 '(' 라면
                    stack.pop()         # '(' 를 뺀다
                                        # ')'를 넣지 않아도 이미 짝을 이루기 때문에 stack 리스트에 담겨진 '('를 삭제한다
                    
                else:
                    stack.append(item)  # '(' 가 아니라면 ')'를 넣어준다 ([ ), )  ])
                
        else:
            stack.append(item)          # 무조건 소괄호 하나를 stack 리스트에 넣는다

    if stack:                           # stak에 item, 즉 소괄호가 남아있다면 짝이 없는 괄호만 남아있는 것이기 때문에 'NO'를 출력한다.
        print("NO")
    else:
        print("YES")

n에 전체 반복문 횟수를 위한 정수를 입력한다. 

소괄호를 하나씩 넣어주며 열린 괄호와 닫힌 괄호를 매칭시켜줄 리스트 변수인 stack을 만들어준다.

 

입력값은 (())()) 로 가정해보자. 

1. 입력값인 line의 값을 item에 하나씩 넣어준다. 현재 item은 열린 괄호 ( 이다. 

2. if stack의 else문으로 인해 stack에 값을 넣어준다. (현재 stack = ['(' ])

3. for문으로 돌아와 item은 현재 열린 괄호 값을 넘겨받는다. 

4. 중첩 if문에서 if item == '(' 에 충족되므로 열린 괄호를 stack에 넣어준다. (현재 stack = ['(', '(' ])

5. for문으로 돌아와 item은 닫힌 괄호 ')' 값을 넘겨받는다. 

6. 중첩 if문에서의 elif item == ')' 에 충족된다. 

이때 stack에 열린 괄호가 있는지 확인하고, 있다면 stack에 있는 열린 괄호 값을 하나 없앤다. 

즉, elif문은 열린 괄호와 닫힌 괄호를 매칭시켜 하나의 소괄호가 완성된다면 해당 소괄호를 소거하는 방식이다. 

이 방식으로 stack은 열린 괄호만 들어오게 되고, 만약 item가 닫힌 괄호 값을 가지고 있다면 stack에 있는 열린 괄호와 매칭시키는 역할을 한다.

결국, 올바른 괄호 문자열이라면 stack에는 빈 리스트가 될 것이고, 아니라면 (닫힌) 괄호를 갖고 있는 리스트가 될 것이다. 

이 점을 이용하여 마지막 if문에서 'YES', 'NO' 를 판별하여 출력한다.