# 난이도 <하>
1. 행운의 바퀴(완료)
https://www.acmicpc.net/problem/2840
# 내 풀이
def solution(n, k):
arr = ["null"]*n
direct = 0
for i in range(k): # 거꾸로 저장중. 즉, 출력은 왼쪽(반시계)으로
s, eng = input().split()
direct = (direct+int(s))%n
if (arr[direct]!="null" and arr[direct]!=eng) or eng in arr[:direct] or eng in arr[direct+1:]: # 행운의 바퀴가 존재하지 않는다.
arr[direct]="!"
#break
else:
arr[direct] = eng
for i in range(n):
if "!" in arr: # !가 있으면
print("!", end="")
break
if arr[direct]=="null":
print("?", end="")
else:
print(arr[direct], end="")
if direct>0:
direct-=1
else:
direct=n-1
n, k = map(int, input().split())
solution(n, k)
- 빈 arr 리스트를 선언한다. 여기에 알아낸 행운의 바퀴를 적을 예정. 처음에 null로 초기화했는데 그냥 ?로 초기화 하고 그대로 출력하는게 좋았을듯.
- 바퀴가 돌아가는 것 == 화살표가 (반대로) 돌아가는 것. (현재 가리키는 인덱스 direct+회전 수 s)%n 을 하면 회전 후 화살표가 가리키는 바퀴로 간다.
- 만약 direct가 null이 아닌데 다른 알파벳을 가리키거나...알파벳이 바퀴의 다른 곳에 위치하고 있으면 ! 을 넣은 후 반복문 break. !은 나중에 출력을 위해 사용할 것임.
- 이제 !가 있으면 ! 출력하고 없으면 알파벳이나 ? 출력하고... direct를 이용해서 출력하고 있다. 저장을 거꾸로(오른쪽으로) 했으므로 출력은 왼쪽으로 해준다. direct를 -1하면서 출력하다가 0이하가 되면 n-1로 저장하기
# 정답 풀이
import sys
input = sys.stdin.readline
"""
[행운의 바퀴]
- 바퀴가 돌아갈 필요 X
- 화살표가 가르키는 인덱스를 회전 정보에 따라 바꿔줌
1. 화살표가 가르키는 칸이 결정되지 않았으면 알파벳을 바퀴에 적는다.
2. 이미 알파벳이 써 있는 경우, 같은 알파벳이 아닌 경우 조건에 해당하는 바퀴 만들 수 없다.
3. 바퀴에 쓰여있는 알파벳은 중복되지 않으므로 동일한 알파벳이 여러 자리에 있을 수 없다.
"""
def solution(n, record):
wheel = ['?'] * n # 바퀴의 상태
is_available = dict() # 해당 알파벳을 새로 쓸 수 있는지 확인하는 딕셔너리
# 모든 알파벳에 대해 우선 True로 저장
# ord(문자) = 아스키코드
# chr(아스키코드) = 문자
ord_a = ord('A')
for i in range(26):
is_available[chr(i + ord_a)] = True
idx = 0 # 화살표가 가르키는 인덱스
for rot, alpha in record:
idx = (idx - int(rot)) % n
# 같은 경우
if wheel[idx] == alpha:
continue
# 다른 알파벳이 써 있거나, 이미 알파벳을 다른 자리에 사용한 경우
if wheel[idx] != '?' or not is_available[alpha]:
return '!'
wheel[idx] = alpha
is_available[alpha] = False
return ''.join(wheel[idx:]+wheel[:idx])
# 입력
n, k = map(int, input().split())
record = [input().split() for _ in range(k)]
print(solution(n, record))
- 마찬가지로 바퀴를 저장하는 wheel 리스트를 ?로 초기화 했다.
- 아스키 코드를 이용하여 문자가 바퀴에 들어갔는지 판별하는 is_available 딕셔너리 선언.
- 처음에 입력받을 때 record 2차원 배열로 입력 받았네...회전수 rot와 알파벳 alpha를 반복해서 가져온다.
- ``.join()구문을 이용하여 리스트를 문자열로 바꾸고 연결하였다.
2. 팰린드롬 만들기
https://www.acmicpc.net/problem/1213
# 내 풀이
def solution(name):
arr = sorted(name)
name2=[]
direct=0
one='null'
while(direct<len(name)):
if arr.count(arr[direct])%2==0:
name2.append(arr[direct])
direct +=2
elif arr.count(arr[direct])%2==1 and arr.count(arr[direct])>2:
name2.append(arr[direct])
if one!='null':
name2=""
break
one = arr[direct]
arr[direct]="?"
direct+=3
else:
if one!='null':
name2=""
break
one = arr[direct]
direct += 1
n = len(name2)
if n<=0 and len(name)>1:
print("I'm Sorry Hansoo")
else:
if one != "null":
name2.append(one)
for i in range(n):
name2.append(name2[n-i-1])
print(''.join(name2))
solution(input())
- 일단 입력받은 name을 정렬해서 리스트 arr에 저장했다.
- 검사할 인덱스를 가리키는 direct를 가지고 name의 길이만큼 반복한다.
- direct가 가리키는 문자가 짝수면 팰린드롬이 될 name2 리스트에 추가한 후 direct +2(다음 문자도 무조건 같으므로)
- 만약 direct가 가리키는 문자가 홀수이고 3이상이라면, name2에 일단 추가하고 하나의 문자만 저장하는 one에 저장한다.
- 단, 이때 one에 다른 문자가 있으면 팰린드롬이 절대 안되므로 탈락.(name2를 null로 만들고 break.)그리고 해당 문자하나를 없애준 후 direct +3(다음 다다음 문자는 무조건 같음)
- 만약 전부 아니면, 즉 direct가 가리키는 문자가 홀수이고 하나만 존재한다면 위를 반복한다. 대신 driect는 +1
- 이제 팰린드롬을 만든다. name2의 길이가 0이하이고 name의 길이가 1보다 크다면 팰린드롬이 만들어지지 않은 것이므로 문자열 출력.
- 만약 팰린드롬이 가능하다면...one의 여부에따라 약간 다르게 팰린드롬의 나머지를 채운 후 print한다.
# 정답 풀이
import sys
from collections import Counter
input = sys.stdin.readline
def make_palindrome(text):
# 각 알파벳의 수를 가지고 팰린드롬 문자열을 리턴하는 함수
# 만들 수 없으면 "I'm Sorry Hansoo" 리턴
part1 = ""
part2 = ""
# Counter(text): 각 문자가 몇개씩 들어있는지 dictionary 형태로 돌려줌
# .items() : key와 value를 짝 지어서 돌려줌
# sorted - 사전적으로 가장 앞서는 문자열을 만들기 위해 정렬
alphabets = sorted(Counter(text).items())
for key, value in alphabets:
if value % 2 == 1:
# 만약 가운데 글자가 있다면 더 이상 불가능
if len(part2) == 1:
# 주의! 문자열에 '가 들어있기 때문에, ""로 감싸주어야 합니다.
return "I'm Sorry Hansoo"
# 비어있다면, 할당
part2 = key
part1 += key * (value // 2)
return part1 + part2 + part1[::-1]
def solution(input):
return make_palindrome(input)
if __name__ == "__main__":
# 입력
text = input().rstrip()
answer = solution(text)
print(answer)
- counter 함수를 이용해서 alphabets 딕셔너리에 {알파벳 : 알파벳 갯수}로 저장 후 정렬하였다.
- 이제 여기서 alphabets를 돌아준다. value값이 홀수라면 part2에 해당 알파벳을 저장한다. 만약 이미 part2가 있다면, 문자열 출력
- 홀수가 아니면 part1에 알파벳*(알파벳 갯수/2)해서 추가.
- return은 part1 + part2 + part1[::-1]로 간단해서 역순 문자열을 추가했다...
- 입력받을 때 혹시 몰라 공백을 제거했네. 안해도 통과는 됐었음.
3. 쇠막대기
https://www.acmicpc.net/problem/10799
# 내 풀이
def solution(stick):
st1=[]
num=0
s=0 # stick 검사
stick = list(stick)
while (s < len(stick)):
# print(st1)
if stick[s]=="(" and stick[s+1]==")":
num += len(st1)
s+=2
continue
else:
if stick[s]=="(":
st1.append("(")
else:
num += 1
st1.pop()
s+=1
print(num)
solution(input())
- 일단 stick을 리스트로 바꾼다. stick을 검사할 인덱스 s와 막대기를 저장하기 위한 스택 st1을 선언.
- 만약 (), 즉 레이저가 있다면 스택에 들어있는 막대기의 수만큼 결과 num에 저장하면 된다. 예를 들어, (((())()))의 경우에 처음 ()를 마주하면 스택에 ((( 3개가 저장되어 있으므로 num +3(st1의 길이)
- ()가 연속으로 붙어있지 않으면 막대기 이므로 잘 판별해서 (인 경우 st1에 넣고 )인 경우 st1에서 하나 빼고 반복해준다.
- 이때 )를 할 경우에는 num+=1을 해주어야 함.
# 정답 풀이
import sys
def solution(s):
answer = 0
stack = []
for i in range(len(s)):
# 여는 괄호인 경우, stack에 push
if s[i] == "(":
stack.append("(")
# 닫힌 괄호인 경우
else:
stack.pop()
# 이전 문자가 '('라면 레이저
if s[i - 1] == "(":
# 레이저이면 stack size만큼 더하기
answer += len(stack)
# 이전 문자가 ')'라면 쇠막대기의 끝
else:
# 쇠막대기의 끝이면 +1
answer += 1
return answer
#str()은 함수이름이므로 s를 사용.
if __name__ == "__main__":
s = sys.stdin.readline().strip()
answer = solution(s)
print(answer)
- 위랑 비슷함.
# 회고
구현은 참 문제 이해부터 어렵다.
겁나 열심히 어찌어찌 풀긴 풀었는데 정답은 쉽게 한거보면 슬프구만.
내가 이해를 잘 못해서 그런가 실제 시험때 반례를 못찾아서 망할 것 같은 느낌임 ㅜ
그리고 대비 문제는 백준으로 주는데 왜 시험은 프로그래머스로 보는가. 하나만 했으면 좋겠다.
'코딩테스트' 카테고리의 다른 글
[Python] ECC 1주차 정리 - 자료구조 (2) | 2024.03.22 |
---|---|
[Python] 2024-1 이퍼 준비(2) (0) | 2024.03.21 |
[python] 프로그래머스 도전~ (0) | 2024.03.18 |
[python] 구현(완전 탐색, 시뮬레이션) (1) | 2024.02.24 |
[Python] 우선순위 큐 (0) | 2024.02.17 |