설명
비어있는 공집합 S가 주어졌을 때,
• add x: S에 x를 추가한다. (1 ≤ x ≤ 20) S에 x가 이미 있는 경우에는 연산을 무시한다.
• remove x: S에서 x를 제거한다. (1 ≤ x ≤ 20) S에 x가 없는 경우에는 연산을 무시한다.
• check x: S에 x가 있으면 1을, 없으면 0을 출력한다. (1 ≤ x ≤ 20)
• toggle x: S에 x가 있으면 x를 제거하고, 없으면 x를 추가한다. (1 ≤ x ≤ 20)
• all: S를 {1, 2, ..., 20} 으로 바꾼다.
• empty: S를 공집합으로 바꾼다
풀이
1. 문자형으로 입력을 받는다. (개행문자도 동시에 제거)
2. 공백이 없는 것과 있는 것을 구분해 조건문을 만든다. isalpha()를 통해 공백 유무를 판별한다.
3. 공백이 없을 때
- 명령어가 'all'일 경우, 반복문을 통해 리스트를 1부터 20까지 채운다.
- 명령어가 'empty'일 경우, 리스트를 비운다.
4. 공백이 있을 때
- 공백을 기준으로 나누고, 숫자로 된 문자는 정수형으로 변환한다. split()을 통해 공백을 기준으로 나눌 수 있다.
- 명령어가 'add'이면서 집합에 해당 정수가 없는 경우 추가한다. append()를 통해 리스트에 추가할 수 있다.
- 명령어가 'remove'이면서 집합에 해당 정수가 있을 경우 제거한다. remove()를 통해 리스트에서 제거할 수 있다.
- 명령어가 'check'일 때
- 집합에 해당 정수가 있으면 1을 출력
- 집합에 해당 정수가 없으면 0을 출력
- 명령어가 'toggle'일 때
- 집합에 해당 정수가 있으면 제거
- 집합에 해당 정수가 없으면 추가
Solution
import sys
input = sys.stdin.readline
m = int(input())
s = [] #공집합
for _ in range(m):
num = input().strip() #1. 문자형으로 입력 받기
if num.isalpha() == True: #문자만 있으면(공백이 없으면)
if num == 'all':
s = [0]*20 #이렇게 안 해주면 out of range 뜸
for i in range(20):
s[i] = i+1
if num == 'empty':
s = []
if num.isalpha() == False: #공백이 있으면
comm, x = num.split() # 공백을 기준으로 나누기
x = int(x)
if comm == 'add' and x not in s: # 명령어가 add일 때 x가 없는 경우 x를 공집합에 추가
s.append(x)
if comm == 'remove' and x in s: # 명령어가 remove일 때 x가 있는 경우 x를 공집합에서 제거
s.remove(x)
if comm == 'check':
if x in s:
print(1)
else:
print(0)
if comm == 'toggle':
if x in s:
s.remove(x)
else:
s.append(x)
TIL
- set(map(str, num)) : 중복된 것을 제거한 리스트를 반환한다.
- list(map(str, num)) : set과 다르게 중복을 제거하지 않는다.
- strip() : 문자열 양끝 공백 문자를 제거한다.
- rstrip()/lstrip() : 문자열 오른쪽/왼쪽 공백 문자를 제거한다.
- replace(old, new) : 원하는 문자로 변경한 새로운 문자열을 반환한다.
숫자, 문자 판별
- isalpha() : 문자열이 모두 문자인지 판별(단, 공백이 있을 경우 False 반환)
- isdigit() : 문자열이 모두 숫자인지 판별(단, 공백이 있을 경우 False 반환)
- isdecimal() : 어떤 문자열이 int형으로 변환이 가능하면 True 반환
- isnumeric() : 숫자값 표현에 해당하는 문자열이면 True 반환 (예: 32,½ ...)
- isalnum() : 숫자와 문자열이 모두 있는지 판별(단, 공백이 있을 경우 False 반환)
효율적인 코드
import sys
input = sys.stdin.readline
s = []
def calc(command, x):
global s
if command == "add":
if x not in s:
s.append(x)
elif command == "remove":
if x in s:
s.remove(x)
elif command == "check":
if x in s:
print(1)
else:
print(0)
elif command == "toggle":
if x in s:
s.remove(x)
else:
s.append(x)
elif command == "all":
s = [i for i in range(1,21)]
elif command == "empty":
s=[]
m = int(input())
for _ in range(m):
command = input().strip()
if command == "all" or command == "empty":
calc(command, 0)
else :
command, x = command.split()
calc(str(command), int(x))
👩💻 회고
공백 때문에 시간을 많이 허비했다. 문자와 숫자를 판별하는 함수를 작성할 때 공백이 있을 경우 False를 반환하는지 몰랐던 탓에 거의 다 풀었는데도 안 돼서 포기할 뻔 했다. ㅜㅜ 그래도 풀어서 다행이었다. 내 코드는 시간이 좀 걸려서 다른 풀이를 봤는데 훨씬 효율이 좋았다. 난 왜 저렇게 생각을 못했을까 한심스럽기도 하다.
숫자와 문자를 구분할 필요가 있을 때 잘 기억해두자.
'BOJ 코딩테스트 > Silver' 카테고리의 다른 글
[BOJ] 1021. 회전하는 큐 (Python/자료구조/Silver 3) (1) | 2024.10.29 |
---|---|
[BOJ] 2161. 카드1 (Python/자료구조/Silver 5) (0) | 2024.10.29 |
BOJ 9655번 : 돌 게임 (Python/구현, DP/Silver 5) (0) | 2024.03.10 |
BOJ 2164번 : 카드2 (Python/자료구조(큐)/Silver 4) (1) | 2024.01.30 |
BOJ 11728번 : 배열 합치기 (Python/Two-Pointer/Silver 5) (4) | 2023.11.09 |