TODAY TIL

안녕하세요! 여러분이 코딩 테스트에서 마주할 수 있는 흥미로운 문제를 소개합니다. 이 문제는 주어진 N×N  크기의 표에서 N번째로 큰 수를 찾아내는 것입니다. 표의 숫자들은 각자의 위에 있는 숫자보다 크도록 구성되어 있습니다. 예를 들어, N=5N = 5일 때 다음과 같은 표가 있을 수 있습니다

 

12  7   9  15  5
13  8  11  19  6
21 10  26  31 16
48 14  28  35 25
52 20  32  41 49

 

이 표에서 다섯 번째로 큰 수를 찾아야 합니다.

입력 설명

  • 첫 번째 줄에는 정수 NN이 주어집니다 (1≤N≤1,5001 \leq N \leq 1,500).
  • 그 다음 NN개의 줄에는 각 줄마다 NN개의 정수가 주어집니다.
  • 숫자들은 −109-10^9 이상 10910^9 이하의 범위를 가지며, 모두 다릅니다.

출력 설명

  • 프로그램은 NN번째로 큰 수를 출력해야 합니다.

해결 전략

이 문제는 단순히 표를 정렬하여 NN번째로 큰 수를 찾는 방식으로는 효율적이지 않습니다. NN의 최대값이 1,500이므로 표에 있는 요소의 수는 최대 2,250,000개가 됩니다. 이 큰 데이터를 다룰 때 메모리와 시간 복잡도를 고려해야 합니다.

최적의 해결책은 다음과 같습니다:

  1. 최소 힙(min-heap)을 사용하여 NN개의 가장 큰 수를 유지합니다.
  2. 한 줄씩 입력을 받아 즉시 처리하여 메모리 사용을 줄입니다.

코드 설명

이제 문제를 해결하는 코드를 단계별로 설명하겠습니다.

 

import sys
import heapq

# 입력을 빠르게 받기 위해 sys.stdin을 사용
input = sys.stdin

# N을 입력받음
N = int(input.readline().strip())
min_heap = []  # 최소 힙을 저장할 리스트

# N개의 행에 대해 각 숫자를 읽어들임
for _ in range(N):
    row = map(int, input.readline().split())  # 한 줄의 숫자를 공백 기준으로 분리하여 처리
    for num in row:
        # 힙의 크기가 N보다 작은 경우 숫자를 추가
        if len(min_heap) < N:
            heapq.heappush(min_heap, num)
        else:
            # N개의 숫자가 이미 힙에 있으면, 새로운 숫자가 최소값보다 큰 경우 교체
            if num > min_heap[0]:
                heapq.heappushpop(min_heap, num)

# 힙의 최솟값이 N번째로 큰 수가 됨
print(min_heap[0])

 

코드 설명 (더 자세히)

  • heapq 모듈은 Python에서 힙 자료구조를 다룰 수 있는 모듈입니다. 이 문제에서는 최소 힙을 사용해 NN개의 가장 큰 수를 유지합니다.
  • sys.stdin.readline(): 표의 크기가 크기 때문에, 입력을 빠르게 받기 위해 input() 대신 sys.stdin.readline()을 사용했습니다. 이는 큰 입력을 더 효율적으로 처리합니다.
  • 히프 유지: 힙에 NN개의 요소만 유지하여 메모리를 절약합니다. 새로운 숫자가 힙의 최솟값보다 클 경우에만 추가하고 기존 최소값을 제거합니다.

예제 실행

입력 예시

5
12 7 9 15 5
13 8 11 19 6
21 10 26 31 16
48 14 28 35 25
52 20 32 41 49

 

이 경우, 다섯 번째로 큰 수는 35입니다. 프로그램은 이 값을 올바르게 출력합니다.

시간 및 공간 복잡도 분석

  • 시간 복잡도: O(N2log⁡N)O(N^2 \log N). 각 숫자마다 힙 연산이 O(log⁡N)O(\log N)이고 총 N2N^2개의 숫자를 처리합니다.
  • 공간 복잡도: O(N)O(N). 힙의 크기는 항상 NN으로 유지되므로 메모리 사용량이 제한적입니다.

결론

이 접근법은 메모리와 시간 효율성을 모두 고려하여 NN번째로 큰 수를 찾는 데 적합합니다. 만약 여러분이 비슷한 문제나 더 좋은 최적화 방법을 알고 있다면 댓글로 알려주세요!

이제 이 코드와 설명을 통해 여러분도 이 문제를 해결할 수 있기를 바랍니다. 코딩 테스트나 실무 프로젝트에서도 도움이 되길 바랍니다!

TODAY TIL

 

안녕하세요! 이번 블로그 포스팅에서는 학교 식당 줄 서기 문제를 해결하는 파이썬 코드와 문제 해결 과정을 공유해보려고 합니다. 이 문제는 많은 학생들이 식당에서 줄을 서고, 식사가 준비되는 과정을 처리하면서 최대 대기 인원을 기록하는 문제입니다. 특히, 입력의 개수가 많기 때문에 효율적인 구현이 필요합니다. 함께 문제를 이해하고 해결해봅시다!

문제 설명

학생들이 학교 식당에 도착하고, 식사가 준비되는 총 n개의 정보가 주어집니다. 이 정보는 두 가지 유형으로 이루어져 있습니다:

  1. 학생 도착 (유형 1 a): 학생 번호 a가 식당에 도착하여 줄을 섭니다.
  2. 식사 준비 (유형 2): 줄의 맨 앞 학생이 식사를 시작합니다.

식당에 도착한 학생은 줄의 맨 뒤에 서게 되며, 식사가 준비되면 줄의 맨 앞에 있는 학생이 식사를 하러 들어갑니다. 우리는 이 과정에서 줄에 서 있는 학생 수가 최대가 되었을 때, 그 순간 줄의 맨 뒤에 있는 학생 번호를 출력해야 합니다.

문제 해결 접근법

이 문제를 해결하기 위해 다음과 같은 접근 방식을 사용했습니다:

  • 큐(Queue) 자료구조를 활용해 학생들이 줄을 서고, 식사를 하러 들어가는 과정을 구현합니다. deque 모듈을 사용하면 큐의 양쪽에서 삽입과 삭제가 빠르게 이루어지므로 적합합니다.
  • 최대 대기 인원과 그 순간의 줄 맨 뒤 학생 번호를 추적하여 결과를 계산합니다.

코드 구현

아래는 문제를 해결하기 위한 파이썬 코드입니다:

from collections import deque
import sys

n = int(input())
queue = deque()
max_wait = 0
last_student = 100001

for _ in range(n):
    action = sys.stdin.readline().strip()
    if action[0] == '1':  # 학생 도착 (유형 1)
        _, student_number = action.split()
        student_number = int(student_number)
        queue.append(student_number)

        if len(queue) > max_wait:
            max_wait = len(queue)
            last_student = queue[-1]
        elif len(queue) == max_wait:
            if queue[-1] < last_student:
                last_student = queue[-1]

    elif action[0] == '2' and queue:  # 식사 준비 (유형 2)
        queue.popleft()

if max_wait == 0:
    last_student = -1

 

코드 설명

  1. 입력 처리 및 초기화
    • n은 총 명령어의 개수를 의미합니다.
    • queue는 학생들이 줄을 서는 대기열을 나타내며, deque()로 초기화됩니다.
    • max_wait는 대기 중인 최대 학생 수를 저장하며, last_student는 그때 줄의 맨 뒤에 있는 학생 번호를 기록합니다.
  2. 학생 도착 처리 (유형 1)
    • 학생 번호가 주어지면 해당 번호를 큐의 맨 뒤에 추가합니다.
    • 대기열 길이가 max_wait보다 크다면 이를 갱신하고, last_student를 현재 줄의 맨 뒤 학생 번호로 업데이트합니다.
    • 만약 대기열 길이가 max_wait와 같다면, 줄의 맨 뒤 학생 번호가 더 작은 경우로 갱신합니다.
  3. 식사 준비 처리 (유형 2)
    • 식사가 준비되면 큐의 맨 앞에 있는 학생을 제거합니다.
  4. 결과 계산
    • 만약 최대 대기 인원이 0이라면, 대기 중인 학생이 없다는 의미로 last_student-1로 설정합니다.

문제 해결의 어려움과 해결 방법

이 문제는 주어진 입력의 개수가 최대 100,000개일 수 있기 때문에 효율적인 입력 처리와 큐의 사용이 필수적입니다. sys.stdin.readline()을 사용하여 입력을 빠르게 처리하고, deque를 활용하여 큐 연산을 효율적으로 구현함으로써 런타임 에러를 피할 수 있었습니다.

마무리

이번 포스팅에서는 학생들이 식당에서 줄을 서는 문제를 해결하는 파이썬 코드를 다뤄보았습니다. 큐 자료구조를 사용해 효율적으로 줄 서기와 식사 과정을 처리하고, 최대 대기 인원과 그때의 학생 번호를 찾는 과정에서 발생할 수 있는 여러 가지 상황들을 고려했습니다. 이 코드가 여러분의 이해에 도움이 되었기를 바랍니다!

 

TODAY TIL

안녕하세요! 오늘은 게임 내에서 연계 기술의 발동 조건을 다루는 흥미로운 문제를 풀어볼 거예요. 임스가 플레이 중인 게임에서는 몇 가지 규칙에 따라 기술이 발동됩니다:

  • 연계 기술은 사전 기술과 본 기술의 조합입니다.
  • 사전 기술 없이 본 기술을 사용하면 기술이 비정상적으로 발동됩니다.
  • 사전 기술은 L, S, 본 기술은 R, K입니다.
  • 숫자 1부터 9까지의 기술은 언제나 단독으로 발동할 수 있습니다.

예를 들어, L을 사용한 후에 R을 사용하면 정상 발동되지만, R만 있으면 발동되지 않아요.

문제 해결 아이디어

이 문제를 해결하려면, 사전 기술이 사용되었는지 확인하면서 본 기술이 발동될 수 있는지를 검토하면 됩니다.

주요 아이디어

  • 사전 기술(L, S)이 나오면 리스트에 저장해두고, 본 기술(R, K)이 나올 때 이 리스트를 확인해 발동 여부를 결정합니다.
  • 숫자 기술(1~9)은 특별한 조건 없이 바로 발동할 수 있습니다.

코드 설명

# 기술의 개수 입력받기 (사용하지 않지만 문제의 형식에 맞추어 필요)
N = int(input())  

# 기술 순서를 문자열로 입력받고 리스트로 변환
skill = list(str(input()))

# 정상적으로 발동된 기술의 개수를 세는 변수
num = 0

# 사용된 사전 기술을 추적하는 리스트
used_list = []

# 기술을 하나씩 확인하며 발동 여부 판단
for i in skill:
    # 사전 기술 'L' 또는 'S'가 나오면 used_list에 추가
    if i == 'L' or i == 'S':
        used_list.append(i)
    
    # 본 기술 'K'가 나왔을 때
    elif i == 'K':
        # 사전 기술 'S'가 있다면 발동 가능
        if 'S' in used_list:
            used_list.remove('S')  # 사용한 'S'는 리스트에서 제거
            num += 1  # 발동된 기술 수 증가
        else:
            break  # 사전 기술 없으면 반복 종료 (스크립트 꼬임)
    
    # 본 기술 'R'이 나왔을 때
    elif i == 'R':
        # 사전 기술 'L'이 있다면 발동 가능
        if 'L' in used_list:
            used_list.remove('L')  # 사용한 'L'은 리스트에서 제거
            num += 1  # 발동된 기술 수 증가
        else:
            break  # 사전 기술 없으면 반복 종료 (스크립트 꼬임)
    
    # 숫자 기술 '1'~'9'는 조건 없이 발동 가능
    else:
        num += 1

# 최종 발동된 기술의 개수 출력
print(num)

설명

  • L이 나오면 사전 기술로 저장됩니다.
  • 1은 사전 기술이 필요 없는 숫자 기술이므로 바로 발동됩니다.
  • S가 나오면 사전 기술로 저장됩니다.
  • 2도 숫자 기술이라 바로 발동됩니다.
  • R이 나오면 L이 사전 기술로 사용되었으므로 발동됩니다.
  • K도 S가 사용된 상태이므로 발동됩니다.

발동된 기술은 총 4개입니다.

 

결론

이 문제는 리스트를 사용해 사전 기술의 사용 상태를 관리하면서 본 기술 발동 여부를 체크하는 방식으로 해결할 수 있었습니다. 코드의 각 부분을 이해하고, 예제를 실행해보며 학습하면 확실히 이해할 수 있을 거예요!

 

TODAY TIL

안녕하세요! 오늘은 n개의 숫자가 적힌 카드를 이용해 특정 규칙에 따라 카드를 처리하는 Python 코드에 대해 설명해드리겠습니다. 이 코드는 카드 게임의 시뮬레이션으로, 주어진 카드가 한 장 남을 때까지의 과정을 출력합니다.

 

문제 설명

사용자는 n개의 카드(숫자 1부터 n까지)를 갖고 있으며, 다음의 규칙을 반복해서 카드가 한 장 남을 때까지 진행합니다:

  1. 제일 위에 있는 카드를 버립니다.
  2. 그다음 제일 위에 있는 카드를 제일 아래로 옮깁니다.

코드 설명

n = int(input())
card = [i for i in range(1, n + 1)]
discard = []

while len(card) != 1:
    discard.append(card.pop(0)) # 제일 위에 있는 카드를 버린다.
    card.append(card.pop(0))    # 제일 위에 있는 카드를 제일 아래로 옮긴다.

for c in discard:
    print(c, end=' ')
print(card[0])

 

코드 단계별 분석

  1. 입력받기: n은 카드의 개수를 나타내며, 사용자가 입력합니다.
  2. 카드 리스트 생성: card는 1부터 n까지의 숫자가 순서대로 저장된 리스트입니다. 예를 들어, n=7일 경우 card = [1, 2, 3, 4, 5, 6, 7]입니다.
  3. 버려진 카드 리스트 초기화: discard는 게임 중 버려진 카드를 저장하기 위한 빈 리스트입니다.
  4. 메인 로직:
    • while len(card) != 1: 조건을 만족할 때까지 반복합니다.
    • discard.append(card.pop(0)): 카드의 맨 위에 있는 카드를 discard에 추가합니다.
    • card.append(card.pop(0)): 카드의 맨 위에 있는 카드를 제거하고, 이를 카드 리스트의 맨 아래로 보냅니다.
  5. 출력:
    • discard 리스트의 내용을 순서대로 출력합니다.
    • 마지막으로 남은 한 장의 카드를 출력합니다.

동작 예시

입력: n = 7

초기 상태:

  • card = [1, 2, 3, 4, 5, 6, 7]
  • discard = []

게임 과정:

  1. discard = [1], card = [3, 4, 5, 6, 7, 2]
  2. discard = [1, 3], card = [5, 6, 7, 2, 4]
  3. discard = [1, 3, 5], card = [7, 2, 4, 6]
  4. discard = [1, 3, 5, 7], card = [4, 6, 2]
  5. discard = [1, 3, 5, 7, 4], card = [2, 6]
  6. discard = [1, 3, 5, 7, 4, 2], card = [6]

출력:

1 3 5 7 4 2
6

 

결과 해석: 버려진 카드의 순서를 출력한 후, 마지막으로 남은 카드를 출력합니다.

이 코드의 핵심은 리스트의 pop(0) 메서드와 append() 메서드를 사용하여 카드의 순서를 처리하는 것입니다. 이를 통해 카드 게임의 규칙을 간단하게 구현할 수 있습니다.

결론

이 코드 예제는 Python의 리스트 메서드를 활용하여 간단한 카드 게임을 시뮬레이션하는 방법을 잘 보여줍니다. 다양한 카드 처리 문제에 응용할 수 있는 좋은 연습이 될 것입니다.

다음에도 재미있는 코드 설명으로 찾아오겠습니다. 읽어주셔서 감사합니다!

 

 

TODAY TIL

안녕하세요! 오늘은 배열에서 연속으로 나타나는 숫자를 제거하는 문제를 해결하는 방법을 소개하겠습니다. 이 문제는 배열 arr에 연속으로 나타나는 숫자가 있을 때, 중복된 숫자를 하나만 남기고 제거하여 반환하는 문제입니다. 문제 풀이를 단계별로 설명하겠습니다.

 

문제 설명

  • 배열 arr가 주어집니다.
  • 배열의 각 원소는 0부터 9까지의 숫자로 이루어져 있습니다.
  • 연속적으로 나타나는 숫자를 하나만 남기고 제거한 배열을 반환합니다.
  • 예를 들어:
    • arr = [1, 1, 3, 3, 0, 1, 1]이면 [1, 3, 0, 1]을 반환해야 합니다.
    • arr = [4, 4, 4, 3, 3]이면 [4, 3]을 반환해야 합니다.

제한사항

  • 배열 arr의 크기: 최대 1,000,000
  • 배열 arr의 원소: 0 이상 9 이하의 정수

 

문제 해결 접근법

1. 문제 이해 및 계획

  • 주어진 배열을 순회하면서 연속된 숫자가 중복인지 확인하고, 중복이 아니면 결과 배열에 추가합니다.
  • 각 숫자를 이전 숫자와 비교하여 중복 여부를 판단합니다.

2. 구현 단계

  • 빈 배열 result를 초기화하여 중복되지 않은 숫자를 저장합니다.
  • previous 변수로 이전 숫자를 저장합니다.
  • arr의 각 원소를 순회하며, previous와 비교해 다를 경우에만 result에 추가합니다.

3. 코드 구현

다음은 문제를 해결하는 Python 코드입니다:

 

def solution(arr):
    result = []  # 결과를 저장할 배열
    previous = None  # 이전 원소를 저장할 변수

    for num in arr:
        # 이전 원소와 다를 때만 결과 배열에 추가
        if num != previous:
            result.append(num)
            previous = num  # 현재 숫자를 이전 숫자로 갱신

    return result

# 테스트 케이스
print(solution([1, 1, 3, 3, 0, 1, 1]))  # 출력: [1, 3, 0, 1]
print(solution([4, 4, 4, 3, 3]))        # 출력: [4, 3]

 

4. 코드 설명

  • result 배열은 중복이 제거된 숫자들을 저장합니다.
  • previous 변수는 이전 숫자를 저장해 연속 중복을 판단합니다.
  • arr의 각 숫자를 순회하며 previous와 비교해 다르면 result에 추가하고, previous를 현재 숫자로 갱신합니다.

5. 시간 및 공간 복잡도

  • 시간 복잡도: O(n)O(n) — 배열을 한 번 순회하므로 매우 효율적입니다.
  • 공간 복잡도: O(n)O(n) — 중복이 제거된 결과 배열을 저장하기 때문입니다.

마무리

이 코드로 연속된 중복 숫자를 손쉽게 제거할 수 있습니다. 배열의 길이가 최대 1,000,000인 경우에도 효율적으로 동작합니다. 문제를 풀면서 알고리즘의 효율성과 Python의 기본 문법을 함께 이해할 수 있는 좋은 예제였습니다.

 

TODAY TIL

 안녕하세요!  오늘은 이 큐를 이용해서 여러 가지 명령어를 처리하는 프로그램을 파이썬으로 구현해볼 거예요!

 

큐(Queue)란?

큐(Queue)는 FIFO(First In, First Out) 구조를 가진 자료 구조에요. 줄을 서서 차례로 서비스를 받는 것처럼, 먼저 들어온 데이터가 먼저 나가는 구조를 가지고 있어요. 반대로 **스택(Stack)**은 LIFO(Last In, First Out) 구조를 가지는데, 나중에 들어온 것이 먼저 나가는 구조를 가지고 있어요.

 

오늘 우리가 구현할 프로그램은 정수를 저장하는 큐에 여러 가지 명령어를 처리하는 프로그램이에요. 여기서 사용될 명령어는 다음과 같아요:

  1. push X: 정수 X를 큐에 넣습니다. 즉, 줄의 끝에 새로운 사람이 들어오는 것과 같아요.
  2. pop: 큐의 가장 앞에 있는 값을 꺼내서 출력해요. 줄의 맨 앞에 있는 사람이 나가는 것과 같은 일이에요. 만약 줄에 아무도 없으면 -1을 출력해요.
  3. size: 현재 큐에 몇 명이 있는지를 출력해요.
  4. empty: 큐가 비어 있으면 1을, 비어 있지 않으면 0을 출력해요.
  5. front: 큐의 가장 앞에 있는 값을 출력해요. 아무도 없으면 -1을 출력해요.
  6. back: 큐의 가장 뒤에 있는 값을 출력해요. 아무도 없으면 -1을 출력해요.

파이썬 코드로 큐 구현하기

아래 코드는 deque를 사용해서 큐를 쉽게 구현한 거예요. deque는 양쪽 끝에서 데이터를 넣고 빼는 데 최적화된 자료구조로, 파이썬의 collections 모듈에서 제공해요.

 

from collections import deque
import sys

input = sys.stdin.read

def queue_operations(commands):
    queue = deque()
    result = []
    for command in commands:
        if "push" in command:
            value = command.split()[1]
            queue.append(value)
        elif command == "pop":
            result.append(queue.popleft() if queue else -1)
        elif command == "size":
            result.append(len(queue))
        elif command == "empty":
            result.append(0 if queue else 1)
        elif command == "front":
            result.append(queue[0] if queue else -1)
        elif command == "back":
            result.append(queue[-1] if queue else -1)
    return result

def main():
    data = input().splitlines()
    commands = data[1:]
    results = queue_operations(commands)
    sys.stdout.write("\n".join(map(str, results)) + "\n")

if __name__ == "__main__":
    main()

 

코드 설명

  1. deque를 사용해 큐 만들기: queue = deque()로 큐를 만들었어요. 이제 queue.append()로 값을 추가하고, queue.popleft()로 값을 꺼낼 수 있어요.
  2. 명령어 처리하기:
    • push X: 큐의 끝에 값을 추가해요.
    • pop: 큐의 앞에 있는 값을 꺼내고, 큐가 비어있다면 -1을 저장해요.
    • size: 현재 큐의 크기를 저장해요.
    • empty: 큐가 비어 있으면 1, 비어 있지 않으면 0을 저장해요.
    • front: 큐의 가장 앞에 있는 값을 저장하고, 큐가 비어있다면 -1을 저장해요.
    • back: 큐의 가장 뒤에 있는 값을 저장하고, 큐가 비어있다면 -1을 저장해요.
  3. 결과 출력하기: 각 명령어의 결과를 리스트에 모아서 마지막에 한 번에 출력해요.

큐의 활용

큐는 여러 가지 상황에서 활용될 수 있어요. 예를 들어, 프린터의 출력 작업을 처리할 때, 먼저 요청된 작업부터 처리하는 데 큐가 사용돼요. 또 너비 우선 탐색(BFS) 같은 알고리즘에서도 큐가 중요한 역할을 해요.

이제 여러분도 큐의 개념과 구현 방법을 잘 이해할 수 있겠죠? 줄을 서는 것처럼 먼저 들어간 것이 먼저 나오는 이 간단한 개념을 파이썬으로 구현해보세요!

마무리

이 글에서는 큐라는 자료구조를 이해하고, 파이썬으로 직접 구현해 보았어요. 큐의 간단한 개념을 다양한 상황에 적용할 수 있으니, 여러 문제를 풀어보면서 직접 사용해 보세요. 이해하기 어려운 부분이나 더 궁금한 점이 있다면 언제든지 댓글로 남겨주세요!

TODAY TIL

 안녕하세요! 오늘은 주어진 여러 개의 테스트 케이스에서 단어들을 반대 순서로 출력하는 Python 코드를 다루어 보겠습니다. 이 문제는 간단한 문자열 처리 문제로, 입출력 포맷에 유의하며 해결하는 방법을 배워보겠습니다.

 

문제 설명

주어진 입력은 N개의 케이스로 구성되어 있습니다. 각 케이스에는 스페이스로 구분된 여러 단어가 있으며, 이를 반대 순서로 출력하는 것이 목표입니다. 각 케이스의 결과는 특정 출력 형식에 맞춰야 합니다.

  • 입력 조건:
    • 첫 줄에는 케이스의 개수 NN이 주어집니다.
    • 각 케이스는 한 줄에 하나씩 입력되며, 단어들은 공백으로 구분됩니다. 라인의 처음과 끝에는 공백이 없습니다.
    • NN과 각 문장의 길이 LL은 1 ≤ LL ≤ 25를 만족합니다.
  • 출력 조건:
    • 각 케이스에 대해 "Case #x: " 형식으로 번호를 출력한 후, 반대 순서로 단어를 출력합니다.

예제 코드

이제 이 문제를 해결하는 Python 코드를 살펴보겠습니다.

# 첫 번째 줄에서 전체 케이스의 개수 N을 입력받는다.
N = int(input())

# 각 케이스를 반복하며 처리한다.
for i in range(1, N + 1):
    # 각 케이스에 대한 단어 입력을 받는다.
    sentence = input().strip()  # strip()을 사용해 앞뒤 공백 제거
    
    # 입력받은 문장을 단어 단위로 분할
    words = sentence.split()
    
    # 단어 리스트를 뒤집는다.
    reversed_words = words[::-1]
    
    # 'Case #x: ' 형식으로 결과를 출력
    print(f"Case #{i}: {' '.join(reversed_words)}")

 

실행 예제

다음은 입력과 출력 예제입니다.

입력:

5
Hello World
Programming is fun
Python is powerful
Reverse these words
Learning is continuous

 

출력:

Case #1: World Hello
Case #2: fun is Programming
Case #3: powerful is Python
Case #4: words these Reverse
Case #5: continuous is Learning

 

코드 설명

  1. input() 함수로 NN을 입력받아 테스트 케이스의 수를 가져옵니다.
  2. strip() 메서드로 각 줄의 앞뒤 공백을 제거하고, split()으로 단어를 리스트로 만듭니다.
  3. 리스트 슬라이싱 [::-1]을 사용하여 단어의 순서를 뒤집습니다.
  4. ' '.join()으로 뒤집힌 단어 리스트를 다시 문자열로 합쳐서 출력 포맷에 맞춰 출력합니다.

마무리

이 코드는 주어진 문제를 해결하는 데 필요한 기본적인 문자열 처리 기법을 포함하고 있습니다. 입출력 포맷과 리스트 조작법을 연습할 수 있는 좋은 예제입니다.

이 코드를 여러분의 Python 학습에 도움이 되기를 바랍니다!

 

TODAY TIL

안녕하세요! 오늘은 코딩 테스트에서 자주 나오는 스택(Stack) 구현 문제를 함께 풀어보겠습니다. 이 문제는 입력으로 주어지는 명령어들을 스택을 통해 처리하는 프로그램을 작성하는 것입니다. 명령어의 종류와 해결 방법을 차근차근 적어보려고 합니다.

 

문제 설명

우리는 다음과 같은 명령어를 처리할 수 있는 스택을 구현해야 합니다:

  • push X: 정수 X를 스택에 넣습니다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고 출력합니다. 스택이 비어 있으면 -1을 출력합니다.
  • size: 스택에 들어있는 정수의 개수를 출력합니다.
  • empty: 스택이 비어 있으면 1, 아니면 0을 출력합니다.
  • top: 스택의 가장 위에 있는 정수를 출력합니다. 스택이 비어 있으면 -1을 출력합니다.

코드 구현

먼저, Python의 sys.stdin.readline()을 사용해 입력을 빠르게 처리하고 각 명령어를 효율적으로 처리하는 코드를 작성하겠습니다.

 

import sys
input = sys.stdin.readline

# 스택 초기화
stack = []

# 명령 수 입력
N = int(input().strip())

# 명령 처리
for _ in range(N):
    command = input().strip()
    
    if command[:4] == "push":
        # push X 처리
        stack.append(int(command.split()[1]))
    elif command == "pop":
        print(stack.pop() if stack else -1)
    elif command == "size":
        print(len(stack))
    elif command == "empty":
        print(1 if not stack else 0)
    elif command == "top":
        print(stack[-1] if stack else -1)

 

코드 설명

  • import sys: Python의 기본 입력 함수 input()은 느릴 수 있기 때문에 sys.stdin.readline()을 사용하여 입력 속도를 최적화했습니다.
  • 스택 구현: Python의 리스트를 사용해 스택을 구현합니다. append()로 push 연산을, pop()으로 pop 연산을 쉽게 처리할 수 있습니다.
  • 명령어 처리: 명령어는 if-elif 조건문으로 처리하며, 명령어가 push로 시작하는지 command[:4] == "push"로 확인해 split()으로 숫자를 추출합니다.
  • 출력 처리:
    • pop: 스택이 비어 있으면 -1을 출력하고, 아니면 마지막 요소를 제거하고 출력합니다.
    • size: len(stack)을 출력합니다.
    • empty: 스택이 비어 있으면 1, 아니면 0을 출력합니다.
    • top: 스택의 마지막 요소를 출력하되, 비어 있으면 -1을 출력합니다.

마무리

이제 이 코드를 통해 코딩 테스트에서 자주 나오는 스택 문제를 해결할 수 있습니다. 입력을 빠르게 처리하고 명령어를 간단하게 구현하여 시간 초과를 방지할 수 있습니다.

이 글이 도움이 되었다면 블로그 구독과 댓글도 부탁드려요! 앞으로도 더 많은 코딩 팁과 문제 풀이를 공유할 예정입니다. 😊

 

TODAY TIL

안녕하세요! 오늘은 마라톤에 참여한 선수 중 단 한 명의 완주하지 못한 선수를 찾는 문제를 해결하는 방법을 다뤄보겠습니다. 이 문제는 코딩 테스트에서 자주 나오는 유형으로, 배열과 정렬을 다루는 좋은 연습이 됩니다.

 

문제 설명

수많은 마라톤 선수들이 마라톤에 참여했는데, 단 한 명의 선수를 제외하고는 모두 완주했습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어졌을 때, 완주하지 못한 선수의 이름을 반환하는 함수를 작성하세요.

제한사항

  • 마라톤에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
  • completion 배열의 길이는 participant의 길이보다 1 작습니다.
  • 참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
  • 참가자 중에는 동명이인이 있을 수 있습니다.

문제 해결 방법

이 문제를 효율적으로 풀기 위해 정렬을 사용한 방법을 설명하겠습니다.

해결 방법 순서

  1. participant와 completion 배열을 정렬합니다.
  2. 정렬된 상태에서 두 배열을 처음부터 비교하면서 일치하지 않는 요소를 찾습니다.
  3. 만약 모든 요소가 일치하면 participant 배열의 마지막 요소가 완주하지 못한 선수입니다.

 

코드 구현

def solution(participant, completion):
    participant.sort()  # 참가자 배열 정렬
    completion.sort()   # 완주자 배열 정렬
    
    # 정렬된 배열에서 비교
    for i in range(len(completion)):
        if participant[i] != completion[i]:
            return participant[i]
    
    # 마지막 참가자가 완주하지 못한 경우
    return participant[-1]

 

예제 테스트

예제 #1:

print(solution(["leo", "kiki", "eden"], ["eden", "kiki"]))  # 결과: "leo"

 

예제 #2

print(solution(["marina", "josipa", "nikola", "vinko", "filipa"], ["josipa", "filipa", "marina", "nikola"]))  # 결과: "vinko"

 

예제 #3:

print(solution(["mislav", "stanko", "mislav", "ana"], ["stanko", "ana", "mislav"]))  # 결과: "mislav"

 

코드 설명

  • participant와 completion 배열을 정렬하여 순서를 맞춥니다.
  • 두 배열을 비교하며 첫 번째로 다른 이름을 반환합니다.
  • 만약 모든 이름이 일치하면 participant 배열의 마지막 이름을 반환합니다. 이는 정렬된 completion 배열의 마지막 요소와 비교했을 때, 남는 한 명이기 때문입니다.

시간 복잡도

이 솔루션은 정렬에 의해 O(nlog⁡n)O(n \log n)의 시간 복잡도를 가집니다. nn은 participant 배열의 길이입니다.

마무리

이 방법은 배열 정렬과 비교를 사용하여 효율적이고 직관적인 솔루션을 제공합니다. 동명이인이 있어도 정확히 동작하도록 설계되었습니다.

TODAY TIL

안녕하세요! 이번 포스팅에서는 폰켓몬 선택과 관련된 흥미로운 코딩 문제를 다뤄보겠습니다. 단계적으로 설명하고 코드 구현을 공유합니다.

 

문제 설명

여러분은 오랜 여행 끝에 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 여러분에게 연구실에 있는 N마리의 폰켓몬 중 N/2마리를 선택해도 좋다고 했습니다. 같은 종류의 폰켓몬은 같은 번호를 가지며, 여러분은 최대한 다양한 종류의 폰켓몬을 선택하고 싶습니다.

문제의 목표: N마리의 폰켓몬 중 최대 N/2마리를 선택할 때, 가장 다양한 종류의 폰켓몬을 선택하는 경우를 찾고, 그때의 폰켓몬 종류의 수를 반환하는 것입니다.

제한사항

  • nums는 폰켓몬의 종류 번호가 담긴 1차원 배열입니다.
  • N은 항상 짝수이며, 1 이상 10,000 이하의 자연수입니다.
  • 폰켓몬의 종류 번호는 1 이상 200,000 이하의 자연수입니다.

단계별 해결 방법

  1. 입력 분석:
    • nums 배열에는 각 폰켓몬의 종류 번호가 포함되어 있습니다.
    • 배열의 길이 N은 항상 짝수입니다. 따라서 N/2마리의 폰켓몬을 선택할 수 있습니다.
  2. 중복 제거:
    • set 자료형을 사용하여 배열에서 중복을 제거하고 고유한 폰켓몬 종류의 수를 구합니다.
  3. 최대 선택 가능한 폰켓몬 수 계산:
    • 선택할 수 있는 최대 종류의 개수는 min(len(unique_pokemon), N // 2)입니다.
      • len(unique_pokemon)은 중복 제거 후 고유한 종류의 개수입니다.
      • N // 2는 선택할 수 있는 폰켓몬의 총 수입니다.
  4. 코드 구현
def solution(nums):
    # 중복 제거 후 고유한 폰켓몬 종류의 수 계산
    unique_pokemon = set(nums)
    
    # 선택할 수 있는 폰켓몬 종류의 최댓값 계산
    return min(len(unique_pokemon), len(nums) // 2)

 

코드 설명

  • set(nums)를 사용하여 nums 배열에서 중복된 종류 번호를 제거합니다.
  • min(len(unique_pokemon), len(nums) // 2)를 사용해 선택할 수 있는 폰켓몬 종류의 최대 개수를 계산합니다.
    • 고유한 폰켓몬 종류의 수(len(unique_pokemon))가 선택 가능한 수(N/2)보다 작으면 모든 고유 종류를 선택할 수 있습니다.
    • 고유한 폰켓몬 종류의 수가 N/2보다 크다면 N/2만큼의 고유 종류만 선택할 수 있습니다.

예제

입력: nums = [3, 1, 2, 3]

  1. set(nums) 결과: {1, 2, 3} (고유한 폰켓몬 종류: 3개)
  2. 선택할 수 있는 최대 개수: len(nums) // 2 = 2
  3. 반환값: min(3, 2) = 2

결과: 최대 2종류의 폰켓몬을 선택할 수 있습니다.

결론

이 문제는 배열에서 중복된 항목을 제거하고 선택할 수 있는 폰켓몬의 종류를 비교하는 간단한 문제였습니다. 중복 제거를 위한 set 사용과 최소값 계산을 통해 다양한 경우를 쉽게 처리할 수 있었습니다.

이제 여러분도 다양한 알고리즘 문제를 해결할 때 중복 제거와 최소값 계산을 활용해 보세요!

+ Recent posts