TODAY TIL

📌 문제 설명

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 숫자들을 사용해 만들 수 있는 가장 큰 정수를 두 수의 "짝꿍"이라고 합니다.
짝꿍을 구하는 규칙은 다음과 같습니다:

  1. X와 Y에 공통으로 나타나는 숫자만 사용합니다.
  2. 공통 숫자 중 가능한 최대 빈도수만큼 사용합니다.
  3. 공통 숫자가 없다면 -1을 반환합니다.
  4. 짝꿍이 0으로만 구성되어 있다면 0을 반환합니다.

예시

  • X = 3403, Y = 13203
    → 짝꿍: 330
  • X = 5525, Y = 1255
    → 짝꿍: 552
  • X = 12345, Y = 67890
    → 짝꿍: -1

💡 문제 해결 방법

이 문제를 해결하기 위한 단계별 접근법은 다음과 같습니다:

Step 1: 숫자의 빈도수 계산

  • X와 Y의 각 숫자가 몇 번 나타나는지를 계산합니다.
  • collections.Counter를 사용하면 간단하게 자릿수의 빈도를 구할 수 있습니다.

Step 2: 공통 숫자와 빈도수 찾기

  • X와 Y의 공통 숫자를 찾고, 각 숫자의 최소 빈도를 기준으로 사용할 수 있는 최대 빈도를 계산합니다.

Step 3: 결과 문자열 생성

  • 공통 숫자를 내림차순으로 정렬하여 가장 큰 숫자를 만듭니다.
  • 예외 처리:
    • 공통 숫자가 없다면 -1 반환.
    • 결과가 0으로만 구성되어 있다면 0 반환.

🖥 코드 구현

from collections import Counter

def solution(X, Y):
    # Step 1: 숫자의 빈도수를 계산
    count_X = Counter(X)
    count_Y = Counter(Y)
    
    # Step 2: 공통 숫자와 최소 빈도 계산
    common_numbers = []
    for num in count_X.keys():
        if num in count_Y:
            # 공통으로 등장하는 숫자 중 가능한 최대 갯수를 추가
            common_numbers.extend([num] * min(count_X[num], count_Y[num]))
    
    # Step 3: 결과 문자열 생성
    if not common_numbers:  # 공통 숫자가 없으면
        return "-1"
    
    # 숫자를 내림차순으로 정렬
    common_numbers.sort(reverse=True)
    result = ''.join(common_numbers)
    
    # 숫자가 모두 0으로만 구성된 경우
    if result[0] == "0":
        return "0"
    
    return result

 

🛠 동작 원리 설명

1. Counter를 활용한 숫자 빈도수 계산

count_X = Counter("3403")  # {'3': 2, '4': 1, '0': 1}
count_Y = Counter("13203") # {'1': 1, '3': 2, '2': 1, '0': 1}

Counter는 각 숫자의 빈도를 딕셔너리 형태로 반환합니다.

2. 공통 숫자와 최소 빈도 찾기

count_X와 count_Y의 키를 비교하여 공통 숫자를 찾고, 가능한 최대 빈도를 리스트에 추가합니다.

common_numbers = ['3', '3', '0']  # 최소 빈도를 기준으로 계산

 

3. 결과 생성

common_numbers를 내림차순으로 정렬하여 가장 큰 숫자를 생성합니다.

common_numbers.sort(reverse=True)  # ['3', '3', '0']
result = ''.join(common_numbers)   # "330"

 

⚙️ 테스트 케이스

# 테스트 케이스
print(solution("3403", "13203"))  # 330
print(solution("5525", "1255"))   # 552
print(solution("12345", "67890")) # -1
print(solution("100", "203045"))  # 0
print(solution("0", "0"))         # 0

 

결과

XY결과

3403 13203 330
5525 1255 552
12345 67890 -1
100 203045 0
0 0 0

💡 문제 풀이 요약

  1. 숫자의 빈도를 계산하여 X와 Y의 공통 숫자를 찾습니다.
  2. 공통 숫자를 기준으로 가능한 최대 빈도를 계산하여 숫자를 조합합니다.
  3. 숫자를 내림차순 정렬하여 가장 큰 짝꿍을 반환합니다.
  4. 특별 케이스 (공통 숫자가 없거나, 결과가 0)를 처리합니다.

⏳ 시간 복잡도

  • 빈도 계산: O(N + M) (X와 Y의 길이)
  • 공통 숫자 탐색 및 정렬: O(10 + K log K) (K는 공통 숫자의 수, 최대 10)

최종 시간 복잡도는 **O(N + M)**입니다.


✏️ 블로그 마무리

이 문제는 문자열 조작과 빈도 계산을 효율적으로 다루는 연습에 적합합니다.
collections.Counter와 같은 내장 모듈을 활용하면 복잡한 문제도 간단히 해결할 수 있습니다.

여러분도 자신만의 풀이법으로 문제를 해결하고 Python을 더욱 깊게 이해해 보세요! 🚀
궁금한 점이나 추가적인 개선 아이디어가 있다면 댓글로 공유해 주세요! 😊

TODAY TIL

문제 소개

햄버거 가게에서 일을 하는 상수는 햄버거를 포장하는 작업을 합니다. 재료들이 정해진 순서로 쌓이면 상수는 이를 포장합니다.
햄버거를 완성할 수 있는 순서는 아래와 같습니다:

  • [빵(1) – 야채(2) – 고기(3) – 빵(1)]

주어진 재료 배열에서 햄버거를 몇 개 포장할 수 있는지 구하는 프로그램을 작성해봅시다.


문제 예시

입력:

ingredient = [2, 1, 1, 2, 3, 1, 2, 3, 1]

출력:

2

설명:

  1. 첫 번째 햄버거는 [1, 2, 3, 1]로 완성됩니다.
  2. 두 번째 햄버거는 [1, 2, 3, 1]로 완성됩니다.
    결과적으로 2개의 햄버거를 포장할 수 있습니다.

문제 해결 접근법

  1. 스택(Stack) 활용:
    • 스택을 사용하여 재료를 추가하면서 햄버거 완성 여부를 확인합니다.
    • 햄버거가 완성되면 스택에서 해당 재료들을 제거합니다.
  2. 햄버거 완성 조건:
    • 스택의 마지막 4개의 재료가 [1, 2, 3, 1]인지 확인합니다.
  3. 시간 최적화:
    • 슬라이싱 대신 stack.pop()을 사용하여 불필요한 연산을 줄입니다.

최적화된 코드

아래 코드는 시간 초과를 방지하기 위해 최적화된 방식으로 작성되었습니다.

def solution(ingredient):
    stack = []  # 재료를 담을 스택
    count = 0   # 포장한 햄버거 개수

    for item in ingredient:
        stack.append(item)  # 스택에 재료 추가

        # 스택의 길이가 4 이상일 때 마지막 4개 요소를 직접 비교
        if len(stack) >= 4:
            if stack[-1] == 1 and stack[-2] == 3 and stack[-3] == 2 and stack[-4] == 1:
                # 햄버거 완성 -> 스택에서 제거
                stack.pop()  # 빵 제거
                stack.pop()  # 고기 제거
                stack.pop()  # 야채 제거
                stack.pop()  # 빵 제거
                count += 1  # 햄버거 개수 증가

    return count

 

코드 실행 과정

입력:

ingredient = [2, 1, 1, 2, 3, 1, 2, 3, 1]
print(solution(ingredient))  # 출력: 2

 

실행 과정:

  1. 스택에 [2] 추가 → 햄버거 완성 불가능.
  2. 스택에 [2, 1] 추가 → 햄버거 완성 불가능.
  3. 스택에 [2, 1, 1] 추가 → 햄버거 완성 불가능.
  4. 스택에 [2, 1, 1, 2, 3, 1] 추가 → 햄버거 완성! 스택에서 제거 → [2, 1].
  5. 나머지 재료를 처리하여 두 번째 햄버거 완성.

결과적으로 햄버거 2개 포장.


시간 및 공간 복잡도

  1. 시간 복잡도:
    • 각 재료에 대해 stack.append()와 비교, 제거 연산이 이루어지므로 O(n).
  2. 공간 복잡도:
    • 스택의 최대 크기는 ingredient와 동일하므로 O(n).

주요 개선 사항

  • 슬라이싱 제거:
    기존의 stack[-4:] 대신, stack[-1], stack[-2], stack[-3], stack[-4]로 개별 접근하여 연산 속도 최적화.
  • 불필요한 복사 연산 최소화:
    stack.pop()을 사용해 스택의 크기를 조정하며, 필요 없는 메모리 복사를 방지.

결론

이 문제는 스택 자료구조를 활용하여 재료의 순서를 관리하고, 햄버거 포장이 완료될 때마다 이를 제거하는 방식으로 효율적으로 해결할 수 있습니다. 최적화된 코드로 시간 초과 문제를 해결했으며, 스택 활용의 기본 개념을 연습하기에도 좋은 문제입니다.

 

 

 

TODAY TIL

환규와 태욱이는 문자열을 가지고 재미있는 "탕수육 게임"을 하고 있습니다. 게임의 규칙은 다음과 같습니다:

  1. 누가 먼저 시작할지 순서를 정합니다.
  2. 먼저 시작하는 사람이 단어의 첫 글자를 말합니다.
  3. 이후 두 사람은 번갈아 가며 다음 글자를 순서대로 말합니다.
  4. 단어의 마지막 글자에 도달하면, 다시 단어의 첫 글자로 돌아가서 반복합니다.
  5. 잘못된 글자를 말하면 게임에서 지게 됩니다.

예를 들어, 단어가 탕수육이라면:

  • 첫 번째 사람: "탕", "육", "수", "탕", "육", "수" ...
  • 두 번째 사람: "수", "탕", "육", "수", "탕", "육" ...

코드 소개

탕수육 게임의 규칙을 바탕으로, 두 사람이 번갈아 문자열을 나누어 가져가는 방식을 Python 코드로 구현했습니다. 이번 포스팅에서는 이 코드를 분석하며 어떻게 동작하는지 알아보겠습니다.

 

코드

def solution(case):
    answer = 0

    for v in case:
        player1 = []
        player2 = []
        for i, c in enumerate(v if (len(v) % 2) == 0 else v * 2):
            if i % 2 == 0:
                player1.append(c)
            else:
                player2.append(c)
        print("".join(player1))
        print("".join(player2))
    return answer


n = int(input())
games = [input() for _ in range(n)]
solution(games)

 

코드 분석

1. 함수 정의

def solution(case):
    answer = 0

 

 

  • 함수 solution은 문자열의 리스트 case를 입력으로 받습니다.
  • answer는 반환 값으로 초기화되지만, 현재는 출력 외에 사용되지 않습니다.

2. 게임 데이터 처리

for v in case:
    player1 = []
    player2 = []

 

 

  • 각 문자열 v를 순회하며, 두 사람의 문자 선택을 저장할 리스트 player1과 player2를 초기화합니다.

3. 문자열 순회 및 나누기

for i, c in enumerate(v if (len(v) % 2) == 0 else v * 2):
    if i % 2 == 0:
        player1.append(c)
    else:
        player2.append(c)

 

 

  • 문자열의 길이에 따라 처리 방식이 달라집니다:
    1. 짝수 길이: 문자열 v 그대로 사용.
    2. 홀수 길이: 문자열 v를 두 번 반복한 문자열 v * 2 사용.
      • 이렇게 하면 홀수 길이에서도 두 사람이 계속 번갈아 가며 문자를 가져갈 수 있습니다.
  • enumerate를 사용해 문자열의 각 문자와 해당 인덱스 i를 가져옵니다:
    • i % 2 == 0: 첫 번째 사람이 선택(player1에 추가).
    • i % 2 == 1: 두 번째 사람이 선택(player2에 추가).

4.결과 출력

print("".join(player1))
print("".join(player2))

 

 

 

  • 두 사람의 선택 결과를 각각 출력합니다.
  • player1과 player2 리스트의 문자를 합쳐 문자열로 변환한 뒤 출력합니다.

5.입력 및 함수 호출

n = int(input())
games = [input() for _ in range(n)]
solution(games)

 

 

  • 입력 데이터:
    • 첫 번째 줄: 게임의 수 n.
    • 이후 n개의 문자열이 게임의 데이터로 입력됩니다.
  • solution 함수에 입력 데이터를 전달하여 결과를 처리합니다.

동작 예시

입력

2
탕수육
ABC

 

처리 과정

  1. 첫 번째 게임: "탕수육"
    • player1: "탕육수" → 첫 번째 사람이 가져간 문자.
    • player2: "수탕육" → 두 번째 사람이 가져간 문자.
    • 출력:
       
탕육수
수탕육

 

2 .두 번째 게임: "ABC"

  • 문자열 길이가 홀수이므로 "ABCABC"로 확장.
  • player1: "ACB" → 첫 번째 사람이 가져간 문자.
  • player2: "BCA" → 두 번째 사람이 가져간 문자.
  • 출력:
     
ACB
BCA

 

최종 출력

탕육수
수탕육
ACB
BCA

 

코드의 한계와 개선 가능성

  1. 반복 확장 방식의 비효율성
    • 홀수 길이 문자열에서 v * 2로 확장하면 메모리를 낭비할 수 있습니다.
    • 이를 대신해 인덱스를 순환적으로 접근하면 더 효율적입니다.
  2. 리턴 값 사용
    • 현재 코드는 결과를 출력만 하고 반환하지 않습니다. 결과를 리스트로 반환하면 더 유연하게 활용할 수 있습니다.

개선된 코드

def solution(case):
    results = []
    for v in case:
        player1 = []
        player2 = []
        n = len(v)
        for i in range(n):
            if i % 2 == 0:
                player1.append(v[i % n])
            else:
                player2.append(v[i % n])
        results.append(("".join(player1), "".join(player2)))
    return results

# 입력 처리
n = int(input())
games = [input() for _ in range(n)]
result = solution(games)

# 결과 출력
for r in result:
    print(r[0])
    print(r[1])

 

결론

이 코드는 두 사람이 번갈아 문자열을 나누는 방식으로 게임을 진행하도록 구현되었습니다. 이를 통해 문자열의 반복적인 패턴을 쉽게 처리할 수 있습니다. 개선된 코드는 더 효율적으로 처리하며, 결과를 반환해 다양한 방식으로 활용할 수 있습니다.

탕수육 게임처럼 단순하지만 재미있는 문제를 통해 문자열 처리와 반복 구조에 대한 이해를 높여보세요! 😊

 

TODAY TIL

📌 문제 설명

H-Index는 과학자의 생산성과 연구 영향력을 나타내는 지표입니다. 한 과학자의 H-Index h는 다음과 같이 정의됩니다:

  • h번 이상 인용된 논문이 h편 이상
  • 나머지 논문이 h번 이하 인용

즉, hh의 최댓값을 구하는 것이 목표입니다.

제한사항

  1. 논문 수 n: 1 이상 1,000 이하
  2. 논문별 인용 횟수: 0 이상 10,000 이하

💡 문제 이해

논문의 인용 횟수 배열을 분석하여, 위 조건을 만족하는 hh의 최댓값을 구합니다.


🛠️ 풀이 방법

문제를 해결하기 위해 다음과 같은 단계를 거칩니다:

  1. 내림차순 정렬
    • 논문의 인용 횟수를 내림차순으로 정렬합니다.
    • 이렇게 하면 인용 횟수가 높은 논문부터 조건을 확인할 수 있습니다.
  2. H-Index 조건 확인
    • 정렬된 배열에서 i+1번째 논문이 i+1번 이상 인용되었는지 확인합니다.
    • 이 조건을 만족하는 i+1h입니다.
  3. 조건 만족 여부
    • 조건을 만족하지 않는 순간 반복을 멈추고, 이전까지 구한 hh의 최댓값을 반환합니다.

 

📄 Python 코드

def solution(citations):
    # 1. 내림차순 정렬
    citations.sort(reverse=True)
    
    # 2. H-Index 계산
    h_index = 0
    for i, citation in enumerate(citations):
        if citation >= i + 1:  # h 조건 확인
            h_index = i + 1
        else:
            break
    
    # 3. 결과 반환
    return h_index

 

🔍 단계별 풀이

  1. 내림차순 정렬
citations.sort(reverse=True)

 

 

  • 논문의 인용 횟수를 내림차순으로 정렬합니다.
  • 예시 입력: [3, 0, 6, 1, 5]
  • 정렬 결과: [6, 5, 3, 1, 0]

2. H-Index 조건 확인

for i, citation in enumerate(citations):
    if citation >= i + 1:
        h_index = i + 1
    else:
        break

 

 

 

  • 논문 i+1번째의 인용 횟수가 i+1 이상인지 확인합니다.
  • 조건이 만족되지 않으면 반복을 멈춥니다.

3. 최댓값 반환

return h_index

 

 

  • 최종적으로 구한 h 값 중 최댓값을 반환합니다.

 

📊 예제 테스트

예제 1

citations = [3, 0, 6, 1, 5]
print(solution(citations))  # 결과: 3

 

 

  • 정렬: [6, 5, 3, 1, 0]
  • hh 계산:
    • 1번째 논문: 6>=1 → h=1
    • 2번째 논문: 5>=2 → h=2
    • 3번째 논문: 3>=3 → h=3
    • 4번째 논문: 1<4 → 조건 불만족, 종료
  • 최종 결과: h=3

예제 2

citations = [10, 8, 5, 4, 3]
print(solution(citations))  # 결과: 4

 

 

  • 정렬: [10, 8, 5, 4, 3]
  • hh 계산:
    • 1번째 논문: 10>=1 → h=1
    • 2번째 논문: 8>=2 → h=2
    • 3번째 논문: 5>=3 → h=3
    • 4번째 논문: 4>=4 → h=4
    • 5번째 논문: 3<5 → 조건 불만족, 종료
  • 최종 결과: h=4

⏳ 복잡도 분석

  • 시간 복잡도
    • 정렬: O(nlog⁡n)
    • 배열 순회: O(n)
    • 총합: O(nlog⁡n)
  • 공간 복잡도
    • 추가 메모리를 사용하지 않으므로 O(1)

✨ 마무리

H-Index 문제는 간단한 조건 확인과 정렬을 통해 해결할 수 있습니다. 중요한 점은 조건을 만족하는 순간까지 hh를 계산하고 최댓값을 반환하는 것입니다.

이 코드를 통해 데이터 분석 및 알고리즘 설계 능력을 키울 수 있으며, 특히 논문이나 데이터를 분석하는 데 유용한 지표 계산에 활용할 수 있습니다.

코드와 풀이에 대한 질문이 있으면 댓글로 남겨주세요!

TODAY TIL

안녕하세요! 😊 오늘은 숫자를 영어로 읽어서 사전순으로 정렬하는 재미있는 문제를 함께 풀어보겠습니다. 이 문제는 파이썬으로 간단하게 구현할 수 있으니, 따라오세요!


문제 설명 📖

  1. 숫자를 숫자 단위로 영어로 읽는다.
    • 예: 79 → seven nine, 80 → eight zero
  2. 영어로 읽은 숫자를 기준으로 사전순 정렬한다.
    • 예: 80 (eight zero) → 79 (seven nine)
  3. 정렬한 숫자를 한 줄에 10개씩 출력한다.

입출력 예시 📝

입력

79 80

 

출력

80 79

 

또 다른 예시

입력

8 15

 

출력

8 11 12 13 15 14 10 9

 

문제 풀이 과정 💡

1단계: 숫자를 영어로 변환하기

숫자를 하나씩 쪼개서 영어로 읽어야 해요.
예를 들어:

  • 79 → seven nine
  • 80 → eight zero

이를 위해 각 자리 숫자를 영어로 변환하는 함수를 만듭니다.

2단계: 정렬 기준 만들기

숫자를 영어로 변환한 후, 영어 문자열 기준으로 정렬합니다.

3단계: 한 줄에 10개씩 출력하기

정렬된 숫자들을 10개씩 묶어서 출력하면 됩니다.

 

파이썬 코드 🐍

def number_to_words(num):
    # 숫자를 영어로 변환하는 함수
    digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
    return " ".join(digits[int(digit)] for digit in str(num))

def solve_number_problem(M, N):
    # M부터 N까지 숫자를 영어로 변환하여 정렬
    numbers = list(range(M, N + 1))
    sorted_numbers = sorted(numbers, key=number_to_words)
    
    # 결과를 한 줄에 10개씩 출력
    for i in range(0, len(sorted_numbers), 10):
        print(" ".join(map(str, sorted_numbers[i:i + 10])))

# 입력 받기
M, N = map(int, input().split())
solve_number_problem(M, N)

 

코드 설명 🛠️

함수 number_to_words

  • 숫자 하나를 받아서 숫자 단위로 영어 문자열로 변환합니다.
  • 예: 79 → seven nine, 80 → eight zero
  •  
digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
return " ".join(digits[int(digit)] for digit in str(num))

 

함수 solve_number_problem

  1. M부터 N까지 숫자를 리스트로 생성합니다.
    • 예: M=79, N=80 → [79, 80]
  2. 숫자를 number_to_words 기준으로 정렬합니다.
    • 예: 79 → seven nine, 80 → eight zero
    • 정렬 결과: [80, 79]
  3. 한 줄에 10개씩 출력합니다.
    • 예: print(" ".join(...))

예제 실행 결과 🎯

입력

8 15

 

출력

8 11 12 13 15 14 10 9

 

문제를 해결하면서 배운 점 📚

  1. 숫자를 영어로 변환하기 위해 문자열 처리를 배웠어요.
  2. sorted 함수로 정렬 기준을 자유롭게 설정하는 방법을 익혔어요.
  3. 한 줄에 10개씩 출력하는 반복문 작성법도 알게 되었어요.

마무리 ✍️

이번 문제는 숫자를 영어로 읽는 독특한 방법과 정렬 기준 설정이 핵심이었습니다. 여러분도 파이썬으로 재미있게 구현해보세요! 😊

TODAY TIL

온라인 게임에서 세준이와 세비가 키운 군대가 대결을 펼친다면 어떻게 될까요? 이번 포스팅에서는 각 군대의 병사들이 전투를 벌여 최후의 승자를 가리는 시뮬레이션 문제를 풀어보려고 합니다. 문제를 간단히 설명하고, 이를 해결하기 위한 파이썬 코드를 함께 살펴볼게요!

문제 설명

세준이와 세비는 각각 군대를 키웠고, 이제 서로의 병사들로 전쟁을 하려고 합니다. 전쟁은 여러 번의 전투로 이루어지며, 매 전투에서 살아남은 병사들 중 가장 약한 병사가 죽게 됩니다. 이 과정을 한 명의 병사만 남을 때까지 반복하며, 최후에 살아남은 병사가 속한 팀이 승리하게 됩니다.

문제의 규칙은 다음과 같습니다:

  • 입력: 첫 번째 줄에 테스트 케이스의 개수 T가 주어집니다. 각 테스트 케이스에서는 두 줄에 걸쳐서 세준이와 세비의 병사 수와 각 병사의 힘이 주어집니다.
  • 출력: 각 테스트 케이스마다 승리한 팀을 출력합니다. 세준이가 이기면 'S', 세비가 이기면 'B', 둘 다 죽으면 'C'를 출력합니다.

병사의 힘은 정수로 주어지며, 이 값이 클수록 강한 병사를 의미합니다. 전투 중에는 두 팀의 병사 중 약한 병사들이 먼저 죽게 되고, 승자를 가릴 때까지 전투가 반복됩니다.

 

입력 예시

1
3 3
5 10 7
6 9 8

 

  • 첫째 줄: 테스트 케이스의 수 (1)
  • 둘째 줄: 세준이의 병사 수 (3명)과 세비의 병사 수 (3명)
  • 셋째 줄: 세준이의 병사들의 힘 (5, 10, 7)
  • 넷째 줄: 세비의 병사들의 힘 (6, 9, 8)

출력 예시

S

 

  • 세준이가 승리한 경우 'S' 출력

파이썬 코드로 문제 풀이하기

이제 이 문제를 해결하기 위한 파이썬 코드를 작성해볼게요. 아래 코드는 주어진 병사들의 힘을 비교하면서 각 팀의 병사들이 하나씩 전멸해가는 과정을 시뮬레이션해줍니다.

n = int(input())
for i in range(n):
    input()  # 테스트 케이스 번호나 팀 이름은 사용하지 않음
    a, b = map(int, input().split())
    s_list = list(map(int, input().split()))
    b_list = list(map(int, input().split()))
    
    # 병사들의 힘을 내림차순으로 정렬하여 가장 강한 병사가 앞에 오도록 함
    s_list.sort(reverse=True)
    b_list.sort(reverse=True)

    # 두 팀 중 한 팀의 병사가 전멸할 때까지 라운드를 진행함
    while s_list and b_list:
        # 세준이의 가장 강한 병사가 세비의 가장 강한 병사보다 강할 경우
        if s_list[0] >= b_list[0]:
            b_list.pop(0)  # 세비의 병사를 제거함
        else:
            s_list.pop(0)  # 세준이의 병사를 제거함

    # 결과 출력: 세준이가 이긴 경우 'S', 세비가 이긴 경우 'B', 둘 다 없는 경우 'C'
    if s_list:
        print('S')
    elif b_list:
        print('B')
    else:
        print('C')

 

코드 설명

  1. 입력받기: 테스트 케이스의 개수를 입력받고, 각 케이스마다 병사들의 힘을 리스트로 입력받습니다.
  2. 내림차순 정렬: 각 팀의 병사들을 내림차순으로 정렬해서 가장 강한 병사가 리스트 앞쪽에 오도록 합니다.
  3. 전투 진행: while 반복문을 사용해 두 팀의 병사들이 남아있을 동안 전투를 계속합니다. 각 라운드마다 가장 강한 병사들끼리 비교하여 상대방을 제거합니다.
  4. 승자 판별: 최종적으로 남은 병사가 있는 팀을 출력합니다. 세준이가 이기면 'S', 세비가 이기면 'B', 모두 없으면 'C'를 출력합니다.

예시를 통해 이해하기

입력 예시에서 세준이의 병사들은 [10, 7, 5]로 정렬되고, 세비의 병사들은 [9, 8, 6]으로 정렬됩니다. 가장 강한 병사들끼리 싸워서 이긴 팀의 병사가 남게 되고, 결국 세준이 팀의 병사들만 남기 때문에 'S'가 출력됩니다.

마무리

이렇게 세준이와 세비의 군대가 전투를 벌이는 시뮬레이션 문제를 해결해 보았습니다. 전투 시뮬레이션 문제를 통해 리스트의 정렬과 반복문을 활용해 문제를 해결하는 방법을 배울 수 있었어요. 각 전투마다 가장 강한 병사들끼리 비교하고, 하나씩 병사가 줄어들면서 최후의 승자를 가리는 방식으로 전투를 진행해요.

이번 포스팅이 도움이 되었길 바라며, 궁금한 점이나 이해가 안 되는 부분이 있다면 언제든지 댓글로 남겨주세요! 😊

TODAY TIL

안녕하세요! 오늘은 재미있는 숫자 조작 문제를 함께 풀어보겠습니다. 이 문제는 주어진 숫자에서 같은 홀수끼리, 또는 같은 짝수끼리만 자리를 교환하여 가장 큰 숫자를 만들어야 하는 도전 과제입니다. 누구나 쉽게 이해할 수 있도록 하나하나 단계별로 풀어보겠습니다.


문제 설명

입력: 양의 정수 num
목표: num의 각 자릿수를 같은 홀수 또는 짝수끼리만 교환하여 만들 수 있는 가장 큰 값을 반환합니다.

단, 홀수와 짝수는 서로 교환할 수 없습니다.

예시

  1. 입력: 1234
    출력: 3412
    설명:
    • 홀수(1, 3)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
    • 짝수(2, 4)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
  2. 입력: 65875
    출력: 87655
    설명:
    • 짝수(6, 8)를 교환하여 큰 값이 앞에 오도록 정렬합니다.
    • 홀수(5, 5, 7)를 교환하여 큰 값이 앞에 오도록 정렬합니다.

문제 해결 방법

  1. 숫자의 홀수와 짝수를 분리합니다.
  2. 각 그룹(홀수, 짝수)을 내림차순으로 정렬합니다.
  3. 원래 숫자의 각 자릿수를 확인하며, 해당 자릿수가 홀수이면 정렬된 홀수 리스트에서 값을 꺼내고, 짝수이면 짝수 리스트에서 값을 꺼냅니다.
  4. 최종적으로 만들어진 숫자를 반환합니다.

코드 구현

아래는 이 문제를 해결하는 Python 코드입니다. 간단한 주석을 추가하여 쉽게 이해할 수 있도록 했습니다.

def largestNumberAfterSwaps(num):
    # 1. 숫자를 문자열로 변환하고 홀수와 짝수 분리
    num_str = str(num)
    odds = [int(d) for d in num_str if int(d) % 2 != 0]  # 홀수 리스트
    evens = [int(d) for d in num_str if int(d) % 2 == 0]  # 짝수 리스트
    
    # 2. 각각 내림차순으로 정렬
    odds.sort(reverse=True)  # 큰 숫자가 앞에 오도록
    evens.sort(reverse=True)
    
    # 3. 원래 숫자의 자리 순서에 맞게 재배치
    result = []
    for digit in num_str:
        if int(digit) % 2 == 0:  # 짝수 자리라면
            result.append(evens.pop(0))  # 짝수 리스트에서 가장 큰 값 추가
        else:  # 홀수 자리라면
            result.append(odds.pop(0))  # 홀수 리스트에서 가장 큰 값 추가
    
    # 4. 리스트를 합쳐서 정수형으로 변환
    return int(''.join(map(str, result)))

# 테스트 예제
print(largestNumberAfterSwaps(1234))  # Output: 3412
print(largestNumberAfterSwaps(65875))  # Output: 87655

 

코드 설명 (누구나 쉽게 이해하기)

  1. 숫자를 문자로 변환하고 홀수와 짝수 분리
    숫자 num을 문자열로 변환합니다. 각 자릿수를 순회하며 홀수와 짝수를 분리합니다.
    예를 들어, num = 65875라면:
    • 홀수 리스트: [5, 5, 7]
    • 짝수 리스트: [6, 8]
  2. 정렬
    홀수와 짝수를 각각 내림차순으로 정렬합니다. 이렇게 하면 가장 큰 숫자가 앞으로 옵니다.
    예를 들어:
    • 정렬된 홀수 리스트: [7, 5, 5]
    • 정렬된 짝수 리스트: [8, 6]
  3. 재배치
    원래 숫자의 각 자릿수를 순회하며, 홀수 자리에는 정렬된 홀수 리스트의 첫 번째 값을 넣고, 짝수 자리에는 정렬된 짝수 리스트의 첫 번째 값을 넣습니다.
    • 원래 숫자: 65875
    • 재배치: [8, 7, 6, 5, 5]
  4. 최종 숫자로 변환
    재배치된 리스트를 문자열로 합친 뒤 정수형으로 변환하여 반환합니다.

예제 설명

입력: 1234

  1. 홀수: [1, 3], 짝수: [2, 4]
  2. 정렬 후: 홀수 [3, 1], 짝수 [4, 2]
  3. 자리 배치: [3, 4, 1, 2]
  4. 결과: 3412

입력: 65875

  1. 홀수: [5, 5, 7], 짝수: [6, 8]
  2. 정렬 후: 홀수 [7, 5, 5], 짝수 [8, 6]
  3. 자리 배치: [8, 7, 6, 5, 5]
  4. 결과: 87655

정리

이 문제는 자릿수의 홀짝성(Parity)을 기준으로 숫자를 정렬하고 재배치하는 간단하지만 재미있는 문제였습니다.
Python의 리스트 처리와 정렬 기능을 활용하면 직관적으로 풀 수 있습니다. 이 코드는 실전 코딩 테스트에서도 활용도가 높으니 꼭 연습해 보세요!

오늘도 코딩 재미있게 하세요! 😊

 

TODAY TIL

파이썬으로 점수 순위 매기기 - 쉬운 풀이 가이드

안녕하세요, 이번 블로그 포스트에서는 파이썬을 이용해 점수 배열을 받아 선수들의 순위를 매기는 문제를 해결해보려고 합니다. 점수에 따라 메달을 부여하고 순위를 매기는 알고리즘 문제를 쉽게 이해할 수 있도록 차근차근 설명드릴게요. 이 포스트를 통해 여러분이 코드 작성 과정을 이해하고, 직접 문제를 풀어볼 수 있도록 돕겠습니다!

문제 설명

우리는 각 선수의 점수가 담긴 배열을 받습니다. 이 배열에는 각 선수의 점수가 고유하게 담겨 있으며, 높은 점수가 높은 순위를 의미합니다. 각 선수는 다음과 같은 순위에 따라 메달 또는 순위 번호를 부여받습니다.

  • 1등: "Gold Medal"
  • 2등: "Silver Medal"
  • 3등: "Bronze Medal"
  • 4등 이후: 해당 순위 숫자

예를 들어, 입력 배열이 [10, 3, 8, 9, 4]이라면 결과는 ['Gold Medal', '5', 'Bronze Medal', 'Silver Medal', '4']가 되어야 합니다.

해결 방법

이 문제를 해결하기 위해 다음과 같은 단계를 거칠 것입니다.

  1. 점수 배열과 인덱스 묶기: 각 점수와 인덱스를 묶어 리스트로 만듭니다. 이렇게 하면 점수를 정렬한 후에도 각 점수가 원래 어디에 있었는지 알 수 있습니다.
  2. 점수 정렬하기: 점수들을 높은 순서대로 정렬합니다. 정렬된 순서에서 1등, 2등, 3등을 각각 메달로 처리하고 나머지 순위를 숫자로 기록합니다.
  3. 결과 배열 생성: 원래 배열에 맞는 순위를 기록한 결과 배열을 반환합니다.

코드 구현

이제 파이썬 코드로 이 문제를 해결하는 방법을 알아보겠습니다. 코드가 이해하기 쉽게 클래스 형태로 작성되어 있습니다.

class Solution:
    def findRelativeRanks(self, score):
        # 점수 배열과 각 인덱스를 묶어 (점수, 인덱스) 형태로 리스트 생성 후 내림차순 정렬
        sorted_score = sorted(enumerate(score), key=lambda x: x[1], reverse=True)

        # 결과 배열 초기화
        ranks = [""] * len(score)

        # 순위에 따라 메달 혹은 순위 번호를 할당
        for i, (idx, value) in enumerate(sorted_score):
            if i == 0:
                ranks[idx] = "Gold Medal"
            elif i == 1:
                ranks[idx] = "Silver Medal"
            elif i == 2:
                ranks[idx] = "Bronze Medal"
            else:
                ranks[idx] = str(i + 1)

        return ranks

# 예제 입력 테스트
solution = Solution()
score1 = [5, 4, 3, 2, 1]
print(solution.findRelativeRanks(score1))  # 출력: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]

score2 = [10, 3, 8, 9, 4]
print(solution.findRelativeRanks(score2))  # 출력: ["Gold Medal", "5", "Bronze Medal", "Silver Medal", "4"]

 

코드 설명

  • 점수 정렬하기: enumerate(score)를 사용해 점수와 인덱스를 함께 묶은 후, 점수를 기준으로 내림차순 정렬했습니다. 이렇게 하면 각 점수가 원래 어느 위치에 있었는지 알 수 있게 됩니다.
  • 결과 배열 생성: 정렬된 점수에 따라 순위를 매기고, 그에 맞는 메달 혹은 순위 숫자를 원래 인덱스 위치에 기록합니다.
  • 메달 할당: 1, 2, 3등에 해당하는 선수에게 각각 "Gold Medal", "Silver Medal", "Bronze Medal"을 부여하고, 나머지는 순위 숫자를 할당합니다.

예제 테스트

  • 입력: [5, 4, 3, 2, 1]
    • 출력: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"]
  • 입력: [10, 3, 8, 9, 4]
    • 출력: ["Gold Medal", "5", "Bronze Medal", "Silver Medal", "4"]

마무리

이렇게 해서 점수 배열을 받아 선수들의 순위를 메달 및 숫자로 표현하는 방법을 알아보았습니다. 간단한 정렬과 반복문을 이용해 문제를 해결할 수 있었죠. 이 문제는 파이썬의 정렬 기능과 인덱스 활용을 배울 수 있는 좋은 예제입니다.

여러분도 비슷한 문제를 풀 때 이런 방식으로 접근해 보세요! 질문이나 궁금한 점이 있으면 언제든지 댓글로 남겨주세요.

안녕하세요! 오늘은 간단하면서도 재미있는 프로그래밍 문제를 함께 풀어보려고 합니다. 문제는 다음과 같습니다:

문제: 여러 학교의 한 해 동안 술 소비량 데이터가 주어졌을 때, 가장 많이 술을 마신 학교의 이름을 출력하라.

 

문제의 배경

입학 OT 때 누구보다도 열심히(?) 놀았던 당신은 자연스럽게 1학년 과대를 맡게 되었습니다. 조인트 엠티를 기획하던 중, 주변 학교 중에서 가장 술 소비가 많은 학교가 궁금해졌습니다. 각 학교의 술 소비량이 주어졌을 때, 가장 많이 술을 마신 학교를 찾는 프로그램을 만들어봅시다.

 

문제 설명

입력

  1. 첫 줄에 테스트 케이스 수 T가 주어집니다.
  2. 각 테스트 케이스의 첫 줄에는 학교의 수 N이 주어집니다.
  3. 이어서 N줄에 걸쳐 각 학교 이름 S와 해당 학교의 술 소비량 L이 주어집니다.
    • 예: Yonsei 20000

출력

  • 각 테스트 케이스마다 가장 술 소비량이 많은 학교 이름을 한 줄씩 출력합니다.

조건

  • 학교의 수 N은 1 이상 100 이하.
  • 소비량 L은 0 이상 10,000,000 이하.
  • 같은 테스트 케이스 내에서 소비량이 동일한 학교는 없습니다.

 

풀이 접근

  1. 입력 데이터를 처리하기
    첫 번째 줄에서 테스트 케이스 수 T를 입력받습니다.
    각 테스트 케이스는 학교의 수 N과 학교 이름 및 소비량 정보가 주어지므로 이를 반복문으로 처리합니다.
  2. 가장 많이 마신 학교 찾기
    각 학교의 이름과 술 소비량을 비교하며 최대 소비량과 그에 해당하는 학교 이름을 기록합니다.
  3. 결과 출력
    테스트 케이스마다 가장 많이 술을 마신 학교의 이름을 출력합니다.

코드 구현

# 테스트 케이스 수 입력
T = int(input("테스트 케이스 수를 입력하세요: "))

# 테스트 케이스 처리
for _ in range(T):
    # 학교의 수 입력
    N = int(input("학교의 수를 입력하세요: "))
    max_school = ""  # 술 소비량이 가장 많은 학교 이름 저장
    max_liquor = 0   # 최대 술 소비량 저장
    
    # N개의 학교 데이터 입력
    for _ in range(N):
        school, liquor = input("학교 이름과 술 소비량을 입력하세요: ").split()
        liquor = int(liquor)
        
        # 최대 소비량과 비교하여 업데이트
        if liquor > max_liquor:
            max_liquor = liquor
            max_school = school
    
    # 결과 출력
    print(max_school)

 

 

코드 설명

1. 테스트 케이스 수 입력

  • 첫 줄에 테스트 케이스 수 T를 입력받습니다.
  • T번 반복하면서 각각의 테스트 케이스를 처리합니다.

2. 학교 데이터 처리

  • 각 테스트 케이스에서 학교의 수 N과 이름-소비량 데이터를 입력받습니다.
  • 최대값 비교를 통해 가장 많이 술을 마신 학교와 그 소비량을 기록합니다.

3. 결과 출력

  • 각 테스트 케이스마다 최대 소비량을 가진 학교의 이름을 출력합니다.

 

예제 실행

입력 예제

2
3
Korea 10000
Yonsei 20000
Ewha 30000
2
SeoulTech 5000
KU 7000

 

출력 예제

Ewha
KU

 

실행 과정 설명

  1. 첫 번째 테스트 케이스:
    • Korea: 10000, Yonsei: 20000, Ewha: 30000 데이터를 비교하여 Ewha가 가장 많이 소비했으므로 출력.
  2. 두 번째 테스트 케이스:
    • SeoulTech: 5000, KU: 7000 데이터를 비교하여 KU가 가장 많이 소비했으므로 출력.

핵심 포인트

  • 입력 데이터 처리: 여러 테스트 케이스를 하나씩 처리하는 반복문 사용.
  • 최댓값 비교: 각 학교의 소비량을 비교하여 현재까지의 최댓값과 이름을 갱신.
  • 문제 해결 능력 향상: 데이터를 순차적으로 처리하면서 최대값을 구하는 방식은 다양한 문제에서 활용 가능!

마무리

이 문제는 간단한 반복문과 조건문을 활용하여 데이터를 처리하는 능력을 기르는 데 매우 유용합니다. 여러분도 직접 코드를 작성하고 실행해 보세요! 😊

궁금한 점이나 피드백이 있다면 댓글로 남겨주세요!

TODAY TIL

🔍 문제 소개

이번 포스팅에서는 배열에서 K번째 수를 찾는 문제를 다룹니다. 이 문제는 정렬 알고리즘의 기초를 연습하기에 적합하며, 간단한 구현으로도 해결할 수 있는 문제입니다. 문제를 이해하고, 순서대로 해결 방법과 코드를 공유하겠습니다!

 

📝 문제 설명

문제

  • 크기가 N인 배열 A가 주어집니다.
  • 배열 A를 오름차순으로 정렬했을 때, 앞에서부터 K번째 수를 출력하세요.

입력 조건

  1. 첫 번째 줄: 정수 N과 K
    • 1 ≤ N ≤ 5,000,000, 1 ≤ K ≤ N
  2. 두 번째 줄: 배열 A의 원소들
    • -10⁹ ≤ Aᵢ ≤ 10⁹

출력 조건

  • 배열을 정렬했을 때 앞에서부터 K번째 수를 출력합니다.

💡 풀이 방법

이 문제는 크게 3단계로 해결할 수 있습니다:

  1. 배열 입력받기
  2. 오름차순 정렬하기
  3. K번째 수 추출하기

🛠️ 코드 구현

Python을 사용하여 문제를 해결하는 코드는 다음과 같습니다:

# 입력 받기
import sys
input = sys.stdin.read
data = input().split()

# N: 배열의 길이, K: 찾고자 하는 위치
N, K = int(data[0]), int(data[1])
A = list(map(int, data[2:]))

# 배열을 정렬
A.sort()

# K번째 수 출력 (1-based index이므로 K-1 사용)
print(A[K - 1])

 

🔎 코드 설명

1️⃣ 입력 받기

  • Python의 sys.stdin.read를 사용해 입력 데이터를 한 번에 받습니다.
  • 첫 번째 줄에서 N(배열 길이)과 K(찾고자 하는 위치)를 가져옵니다.
  • 두 번째 줄에서 배열 A를 리스트로 변환합니다.

2️⃣ 배열 정렬

  • 배열 A를 sort() 메서드를 사용해 오름차순 정렬합니다.
    Python의 sort()는 Timsort 알고리즘을 기반으로 작동하며, 시간 복잡도는 **O(N log N)**입니다.

3️⃣ K번째 수 추출

  • 배열은 0부터 시작하는 0-based index입니다. 따라서 K번째 수를 찾으려면 A[K-1]을 사용합니다.

🧩 예제 풀이

예제 입력

5 2
4 1 3 2 5

 

풀이 과정

  1. 배열의 길이 N = 5, K번째 위치 K = 2
    배열 A = [4, 1, 3, 2, 5]
  2. 배열 정렬:
A.sort() → [1, 2, 3, 4, 5]

 

3. K번째 수 추출:

A[K-1] = A[1] = 2

 

4. 출력 결과:

2

 

⏱️ 시간 복잡도 분석

  1. 배열 정렬: 정렬의 시간 복잡도는 O(N log N)
  2. K번째 수 추출: 상수 시간 O(1)

따라서 전체 시간 복잡도는 **O(N log N)**입니다.


📌 추가 팁: 더 효율적인 방법은 없을까?

만약 배열이 매우 커서 메모리나 시간 효율이 중요하다면, Quickselect 알고리즘을 사용해 K번째 수를 찾을 수 있습니다. Quickselect는 평균적으로 **O(N)**의 시간 복잡도로 실행됩니다. 그러나 이 문제에서는 Python의 내장 정렬을 사용하는 것이 가장 간단하고 안정적인 방법입니다.


✅ 마무리

배열에서 K번째 수를 찾는 문제는 정렬 알고리즘과 리스트 활용법을 연습할 수 있는 좋은 문제입니다. 이번 포스팅에서는 Python의 기본 정렬 메서드인 sort()를 사용하여 문제를 간단히 해결했지만, 다른 알고리즘을 적용해보는 것도 추천합니다!

+ Recent posts