https://www.acmicpc.net/problem/17413
s = input().rstrip()
stack = []
res = ""
inside_tag = False
for ch in s:
if ch == "<":
while stack:
res += stack.pop()
inside_tag = True
res += ch
elif ch == ">":
inside_tag = False
res += ch
elif inside_tag:
res += ch
elif ch == " ":
while stack:
res += stack.pop()
res += " "
else:
stack.append(ch)
while stack:
res += stack.pop()
print(res)
inside_tag로 태그 내부/외부 구분< → 태그 시작, > → 태그 끝.inside_tag = True/False 로 현재 위치가 태그 안인지 밖인지를 추적.res(결과 문자열)를 따로 유지print() 하지 않고,res는 최종 결과를 구성하는 완전한 문자열 버퍼 역할을 한다." ") 시점 구분pop() 하여 역순으로 res에 추가.<tag> 밖 단어만 정확히 뒤집히고, 태그나 공백의 원형은 유지된다.요약하자면 핵심은
문자 단위 순회 + 상태 전환(inside_tag) + 스택을 이용한 부분 뒤집기
였다.
https://www.acmicpc.net/problem/10799
import sys
input = sys.stdin.readline
s = input().strip()
stack = []
count = 0
for i in range(len(s)):
if s[i] == "(":
stack.append("(")
else:
stack.pop()
if s[i-1] == "(": #laser
count += len(stack)
else:
count += 1
print(count)
배운점_ 코드는 간단해보이는데 솔직히 너무 어려웠다;; 거의 손도 못대서, 그냥 외워버림
(1) stack 을 사용하되 레이저를 사용
()(((()())(())()))(())
예시
| 인덱스 | 문자 | 현재 스택 상태 | 설명 | 조각 수 변화 | 누적 count |
|---|---|---|---|---|---|
| 0 | ( | ( | 쇠막대기 시작 | — | 0 |
| 1 | ) | 레이저 (() 조합) → 자른 조각 없음 | +0 | 0 | |
| 2 | ( | ( | 새 막대 시작 | — | 0 |
| 3 | ( | ( ( | 새 막대 시작 | — | 0 |
| 4 | ( | ( ( ( | 새 막대 시작 | — | 0 |
| 5 | ( | ( ( ( ( | 새 막대 시작 | — | 0 |
| 6 | ) | ( ( ( | 레이저! 스택길이=3 → +3조각 | +3 | 3 |
| 7 | ( | ( ( ( ( | 새 막대 시작 | — | 3 |
| 8 | ) | ( ( ( | 레이저! 스택길이=3 → +3조각 | +3 | 6 |
| 9 | ) | ( ( | 쇠막대기 끝 → 마지막조각 +1 | +1 | 7 |
| 10 | ( | ( ( ( | 새 막대 시작 | — | 7 |
| 11 | ( | ( ( ( ( | 새 막대 시작 | — | 7 |
| 12 | ) | ( ( ( | 레이저! 스택길이=3 → +3조각 | +3 | 10 |
| 13 | ) | ( ( | 쇠막대기 끝 → 마지막조각 +1 | +1 | 11 |
| 14 | ) | ( | 쇠막대기 끝 → 마지막조각 +1 | +1 | 12 |
| 15 | ( | ( ( | 새 막대 시작 | — | 12 |
| 16 | ) | ( | 레이저! 스택길이=1 → +1조각 | +1 | 13 |
| 17 | ) | 쇠막대기 끝 → 마지막조각 +1 | +1 | 14 | |
| 18 | ( | ( | 새 막대 시작 | — | 14 |
| 19 | ( | ( ( | 새 막대 시작 | — | 14 |
| 20 | ) | ( | 레이저! 스택길이=1 → +1조각 | +1 | 15 |
| 21 | ) | 쇠막대기 끝 → 마지막조각 +1 | +1 | 16 | |
| 22 | ⚠️ 마지막 큰 막대의 닫힘 시 조각 +1 (누락 보정) | +1 | 17 ✅ |
)는 마지막 조각 1개를 더 만듦.'(' → 스택에 push (새 막대 시작)
')'이 나오면:
'(' → 레이저 → stack.pop() 후 count += len(stack)stack.pop(), count += 1마지막까지 더한 총 count = 17
https://www.acmicpc.net/problem/1935
N = int(input())
expr = input().strip()
values = [int(input()) for _ in range(N)]
#print(values)
op = ["+","-","*","/"]
stack = []
for ch in expr:
if ch.isalpha():
stack.append(values[ord(ch) - ord("A")])
else:
a = stack.pop()
b = stack.pop()
if ch == "+":
stack.append(b+a)
elif ch == "-":
stack.append(b-a)
elif ch == "*":
stack.append(b*a)
else:
stack.append(b/a)
for i in stack:
print(f"{i:.2f}")
1️⃣ 변수 매핑 (values 리스트 + ord 사용)
values 리스트를 사용한다.ord(ch) - ord('A')로 ‘A’를 0, ‘B’를 1처럼 인덱스로 변환하여 values에 접근하면2️⃣ 스택 연산 순서 주의
피연산자는 스택에 push, 연산자를 만나면 두 개를 pop한다.
여기서 두 번째 pop된 값이 왼쪽 피연산자, 첫 번째 pop된 값이 오른쪽 피연산자다.
따라서 항상
a = stack.pop()
b = stack.pop()
로 두고, b - a, b / a 순으로 계산해야 한다.
(연산자를 만난 뒤 pop하는 방식으로 쓰면 헷갈리고 코드 가독성이 떨어진다.)
3️⃣ 출력 형식 — 소수점 둘째자리
최종 결과를 소수점 둘째 자리까지 출력해야 하므로
print(f"{value:.2f}")
형식을 사용한다.
이 밖에도 알아두면 좋은 포맷팅:
f"{num:05d}" → 정수 앞에 0을 채워 5자리로 (00042)f"{num:.3f}" → 소수점 아래 3자리까지 표시 (3.142)즉, 핵심은
① 문자 인덱싱을 ord로 매핑,
② 스택의 연산 순서 유지,
③ 포맷팅으로 정확한 출력 형식 맞추기
이 세 가지다.