일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 스탠실 버퍼 튜토리얼
- 리액트 네이티브 설치 오류
- 싸이월드
- C++
- GitHub
- react
- Expo
- html
- react native 타입스크립트
- react native typescript navigate
- react native ios 기기 연결
- node.js
- 스탠실 버퍼 사용
- 스탠실 버퍼 시작
- javascript
- react native mac
- 벡터와 리스트의 차이
- unity stencil buffer
- react native accessible
- c++ using
- node
- react native typescript navigation
- react native
- stencil buffer
- react native typescript
- CSS
- c++ 정보은닉
- 리액트 네이티브 맥
- react-native
- cyworld
- Today
- Total
혀니의 이거저거 뿌시기
백준 17609 회문 (파이썬 / 문자열) 본문
17609번: 회문
각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.
www.acmicpc.net
골드5문제였다.....
처음에는 쉬운 줄 알았다. 바로 통과 아니야? 했다.. 하지만 우여곡절이 정말 많았다.
<첫 번째 코드>
from collections import deque
T = int(input())
for i in range(T):
str = deque(input())
stat = 0
while str:
if str[0] != str[len(str) - 1]:
if str[1] == str[len(str) - 1]:
str.popleft()
elif str[0] == str[len(str) - 2]:
str.pop()
else:
stat = 2
break
stat = 1
else:
str.popleft()
if str:
str.pop()
print(stat)
방법은 str을 deque으로 만들어서 str이 없어질 때까지 맨 앞과 뒤를 비교해서 같으면 없애고 다르면 그 옆에있는 값들을 비교해서 깎아내려가는 것이었다.
문제) abbab같은 옆의 문자와 비교해야할 문자가 같은 경우 성립할 수 없었다.
<두 번째 풀이>
from collections import deque
T = int(input())
def rout(str, start, end):
st = True
for i in range((len(str)) // 2):
if str[i + start] != str[end - i]:
st = False
break
return st
for i in range(T):
str = deque(input())
stat = 0
while str:
if str[0] != str[len(str) - 1]:
if rout(str, 1, len(str) - 1):
str.popleft()
elif rout(str, 0, len(str) - 2):
str.pop()
else:
stat = 2
break
stat += 1
else:
str.popleft()
if str:
str.pop()
print(stat if stat < 2 else 2)
위의 문제를 해결하기 위해서 각각의 if문에 들어갈 때마다 이 안에 있는 값들이 회문인지를 for문을 돌리며 검사하는 코드를 짰다.
문제) 예상하기도 했지만 이중 for문을 돌기 때문에 시간초과가 떴다.
<정답 코드>
다른 블로그에서 해답을 찾았다.
import sys
def rot(str):
left = 0
right = len(str) - 1
while left < right:
if str[left] == str[right]:
left += 1
right -= 1
else:
if left < right - 1:
temp = str[:right] + str[right + 1:]
if temp[:] == temp[::-1]:
return 1
if left + 1 < right:
temp = str[:left] + str[left + 1:]
if temp[:] == temp[::-1]:
return 1
return 2
T = int(input())
for i in range(T):
print(rot(sys.stdin.readline().strip()))
난 아직 이러한 방식으로 코드를 짜 본적이 별로 없지만 비슷한 형태를 목격한 적이 있다.
바로 퀵소트같은 알고리즘에서이다.
left, right로 양 끝의 index를 참조해가면서 left와 right가 교차되기 전까지 조건에 맞게 문자 하나를 빼 가면서 그 상태에서 회문이 가능하다면 1을, 불가능하다면 2를, 처음부터 회문이 된다면 0을 하는 방식이다.
(그래서 이 문제의 유형이 두 포인터 이기도 하다.)
또한, str[::]와 같은 방식을 사용하려면 deque를 쓸 수 없다는 것도 알았다..
나중에 문제 풀 때 잘 참조하자...
'알고리즘 공부(C++)' 카테고리의 다른 글
백준 1021 회전하는 큐 (파이썬 / 자료구조) (0) | 2022.09.28 |
---|---|
백준 1735 분수 합 파이썬 (0) | 2022.09.18 |
17413 단어 뒤집기2 (파이썬 / 문자열) (0) | 2022.09.14 |
백준 1003 피보나치 함수 (다이나믹 프로그래밍 / 파이썬) (0) | 2022.09.13 |
백준 15663 N과 M(9) 백트래킹 파이썬 (2) | 2022.09.11 |