20260409 오늘의 학습: COS Pro 기출 3회차 완료

Yesol Lee·2026년 4월 9일

COS Python

목록 보기
15/20

지난 학습 요약

  • 구름EDU 기출 3회차 전반부(1, 2, 3, 6, 7번) 5문제 전부 1차 정답
  • 배열 회전, 팰린드롬, 소수 판별, 카프리카 수, 비숍 공격 범위 학습
  • 3회차 나머지 5문제(4, 5, 8, 9, 10번) 풀이 예정이었음

오늘 수업 계획

  • 구름EDU 기출 3회차 나머지 5문제 풀이 (4, 5, 8, 9, 10번)
  • 디버깅 2문제 + 빈칸 1문제 + 함수 작성 2문제

학습 내용 정리

1. break vs continue vs pass — 디버깅 (문제 8)

선풍기 대수를 구하는 디버깅 문제. 교실마다 선풍기 4대가 있고, 선풍기 1대당 k명에게 바람을 보낼 때, 추가로 필요한 선풍기 총 대수를 구하는 코드에서 한 줄 수정.

버그: breakcontinue

for s in student:
    s -= 4 * k
    if s <= 0:
        break       # ❌ 루프 전체 종료 — 뒤 교실 무시
        continue     # ✅ 이 교실 건너뛰고 다음으로
    answer += (s + k - 1) // k

break / continue / pass 차이 정리

키워드동작
break루프 전체 종료
continue이번 반복 건너뛰고 다음 반복으로
pass아무것도 안 함 (다음 줄 실행)

이 문제에서 pass를 쓰면 if 블록 이후의 answer += ... 줄이 실행되어 0이하 값이 더해질 수 있다. continue가 정확한 답이다.


2. 슬라이딩 윈도우 — 디버깅 (문제 9)

팝업스토어를 열 최적의 날짜를 찾는 문제. n일간의 매출액 중 연속 k일의 합이 최대인 값을 구한다.

슬라이딩 윈도우 패턴

연속 k개 합을 구할 때, 매번 sum()을 쓰면 느리다. 대신 "하나 빼고 하나 더하기"로 O(n)에 해결한다.

# 첫 윈도우 합
rsum = sum(revenue[0:k])
answer = rsum

# 윈도우를 한 칸씩 밀기
for i in range(k, len(revenue)):    # ← i는 k부터!
    rsum = rsum - revenue[i - k] + revenue[i]
    if answer < rsum:
        answer = rsum

핵심 포인트:

  • 첫 윈도우(0~k-1)는 이미 구했으니, for문은 i=k부터 시작
  • i는 항상 윈도우의 오른쪽 끝을 가리킴
  • revenue[i-k]는 빠지는 왼쪽 값, revenue[i]는 새로 들어오는 오른쪽 값

예시 (k=4, [1, 1, 9, 3, 7, 6, 5, 10]):

첫 윈도우: [1, 1, 9, 3]              → sum = 14
i=4:        1 [1, 9, 3, 7]           → 14 - 1 + 7 = 20
i=5:           [9, 3, 7, 6]          → 20 - 1 + 6 = 25
i=6:              [3, 7, 6, 5]       → 25 - 9 + 5 = 21
i=7:                 [7, 6, 5, 10]   → 21 - 3 + 10 = 28 ← 최대!

수업 중 질문: "range 시작값으로 0이나 1이 아닌 k를 쓰는 이유?"
→ i가 len을 넘지 않으면서도 i-k가 0부터 시작하게 하려는 것. i가 윈도우의 오른쪽 끝이기 때문에, i=k일 때 첫 번째로 빠지는 값이 revenue[0]이 된다.


3. 클래스 상속 + 메서드 오버라이드 — 빈칸 채우기 (문제 10)

미용실(HairShop)과 레스토랑(Restaurant)이 Shop을 상속받아 각각 예약 조건을 다르게 구현하는 문제. 빈칸 8개를 채워야 한다.

예약 조건

  • 미용실: 인원수 1명만, 시간 겹침 불가
  • 레스토랑: 인원수 2~8명, 같은 시간 최대 2팀까지
class HairShop(Shop):                        # 상속
    def __init__(self):
        super().__init__()

    def reserve(self, customer):             # 메서드 오버라이드
        if customer.num_of_people != 1:      # 1명 아니면 거절
            return False
        for r in self.reserve_list:
            if r.time == customer.time:      # 시간 겹침 체크
                return False
        self.reserve_list.append(customer)
        return True
class Restaurant(Shop):
    def reserve(self, customer):
        if customer.num_of_people < 2 or customer.num_of_people > 8:
            return False
        count = 0
        for r in self.reserve_list:
            if r.time == customer.time:
                count += 1
        if count >= 2:          # for문 밖에서 판단!
            return False
        self.reserve_list.append(customer)
        return True

포인트: Restaurant의 count >= 2 체크는 for문 에서 한다. 안에서 하면 아직 다 세지도 않았는데 판단하게 될 수 있다.

이 문제는 10차 세션에서 배운 클래스 상속 개념으로 8개 빈칸 전부 1차 정답!


4. 문자열 겹침 이어붙이기 — 함수 작성 (문제 4)

두 문자열 s1, s2를 이어붙이되, 한쪽 끝과 다른 쪽 시작이 겹치면 한 번만 쓴다. s1+s2, s2+s1 중 더 짧은 길이를 return.

풀이 핵심: 두 방향 겹침 중 최대값 찾기

def solution(s1, s2):
    answer = 0
    std_len = min(len(s1), len(s2))
    dup_len = 0

    for i in range(1, std_len + 1):    # ← +1 주의!
        # s2 뒤에 s1 붙이는 경우 (s1 시작 = s2 끝)
        if s1[:i] == s2[-i:]:
            dup_len = i
        # s1 뒤에 s2 붙이는 경우 (s1 끝 = s2 시작)
        if s1[-i:] == s2[:i] and i > dup_len:
            dup_len = i

    answer = len(s1) + len(s2) - dup_len
    return answer

주의: range(1, std_len)이 아니라 range(1, std_len + 1) — 겹침이 짧은 쪽 문자열 전체 길이와 같을 수 있기 때문이다.


5. 전광판 스크롤 — 함수 작성 (문제 5)

화면에 14자를 표시하는 전광판에서, 문구가 왼쪽으로 1초에 한 칸씩 스크롤된다. 주어진 초(second)에 화면에 보이는 문자열을 return.

풀이 핵심: 밑줄 패딩 + text*2로 순환 처리

def solution(phrases, second):
    answer = ''
    text = phrases.zfill(len(phrases) * 2).replace("0", "_")
    d_text = text * 2
    cal_sc = second % len(text)
    answer = d_text[cal_sc:len(phrases) + cal_sc]
    return answer

단계별 동작:
1. zfill(28): "happy-birthday" → "00000000000000happy-birthday" (14개의 0 + 문구)
2. .replace("0", "_"): "______________happy-birthday" (밑줄 14개 + 문구)
3. text * 2: 문자열을 두 번 이어붙여서 순환 처리
4. second % len(text): 나머지 연산으로 반복 주기 처리
5. 슬라이싱으로 14글자 추출

수업 중 질문: "왜 text를 두 번 붙이나요?"
→ 슬라이싱이 문자열 끝을 넘어가면 잘린다. 예를 들어 t=20일 때 text[20:34]인데 text는 28자라 8글자만 나온다. text*2로 56자를 만들어두면 어디서 잘라도 항상 14글자가 보장된다.

주의: str은 Python 내장함수이므로 변수명으로 사용하면 안 된다! text, display_str 같은 이름을 쓰자.


6. 음수 인덱스와 슬라이싱 복습

문제 4에서 s1[-i:] 같은 표현이 나왔는데, 왜 이게 "뒤에서 i글자"가 되는지 정리.

음수 인덱스 = 뒤에서부터 세는 위치

s = "hello"
#     h  e  l  l  o
# 양수: 0  1  2  3  4
# 음수:-5 -4 -3 -2 -1

슬라이싱에서 생략된 부분

s[-1:]은 사실 s[-1:len(s)]와 같다. 뒤쪽을 생략하면 끝까지라는 뜻.

s[-1:]   # s[-1:5] → "o"       (뒤 1글자)
s[-2:]   # s[-2:5] → "lo"      (뒤 2글자)
s[-3:]   # s[-3:5] → "llo"     (뒤 3글자)

마찬가지로 s[:3]s[0:3]과 같다. 앞쪽 생략하면 처음부터.

주의: 음수 인덱스 ≠ 역순 출력

수업 중 질문: "음수 인덱스를 쓰면 거꾸로 출력되나요?"
→ 아니다! 음수는 시작 위치만 뒤쪽일 뿐, 출력 순서는 왼→오 그대로다.

s = "hello"
s[-3:]    # "llo" ← 뒤에서 3글자를 순서대로
s[::-1]   # "olleh" ← 이게 진짜 역순! (step이 -1)

역순은 step에 -1을 줘야 한다. 음수가 나오는 위치가 다르다:

  • 인덱스의 음수 → 위치 (어디서부터)
  • step의 음수 → 방향 (어느 쪽으로)
# 뒤 3글자를 거꾸로 출력하려면?
s[:-4:-1]   # "oll" ← start 생략(=끝), end=-4(=index 1) 전까지, step=-1

오늘의 결과

  • 기출 3회차 나머지 5문제 완료 → 3회차 전체 10문제 완료!
  • 1차 정답률 3/5 (60%) — 슬라이딩 윈도우, 전광판 스크롤은 힌트 후 해결
  • 다음 학습: 구름EDU 기출 4회차 (학습용 마지막)
profile
문서화를 좋아하는 개발자

0개의 댓글