정보
문제 바로가기 [클릭]
난이도: Gold5
관련 개념: #구현 #투포인터 #문자열
조건
시간 제한 | 메모리 제한 |
---|---|
1 초(추가 시간 없음) | 512 MB |
문제
회문(回文) 또는 팰린드롬(palindrome)은 앞 뒤 방향으로 볼 때 같은 순서의 문자로 구성된 문자열을 말한다. 예를 들어 ‘abba’ ‘kayak’, ‘reviver’, ‘madam’은 모두 회문이다. 만일 그 자체는 회문이 아니지만 한 문자를 삭제하여 회문으로 만들 수 있는 문자열이라면 우리는 이런 문자열을 “유사회문”(pseudo palindrome)이라고 부른다. 예를 들어 ‘summuus’는 5번째나 혹은 6번째 문자 ‘u’를 제거하여 ‘summus’인 회문이 되므로 유사회문이다.
여러분은 제시된 문자열을 분석하여 그것이 그 자체로 회문인지, 또는 한 문자를 삭제하면 회문이 되는 “유사회문”인지, 아니면 회문이나 유사회문도 아닌 일반 문자열인지를 판단해야 한다. 만일 문자열 그 자체로 회문이면 0, 유사회문이면 1, 그 외는 2를 출력해야 한다.
입력
입력의 첫 줄에는 주어지는 문자열의 개수를 나타내는 정수 T(1 ≤ T ≤ 30)가 주어진다. 다음 줄부터 T개의 줄에 걸쳐 한 줄에 하나의 문자열이 입력으로 주어진다. 주어지는 문자열의 길이는 3 이상 100,000 이하이고, 영문 알파벳 소문자로만 이루어져 있다.
출력
각 문자열이 회문인지, 유사 회문인지, 둘 모두 해당되지 않는지를 판단하여 회문이면 0, 유사 회문이면 1, 둘 모두 아니면 2를 순서대로 한 줄에 하나씩 출력한다.
예제 입출력 1
입력
1
2
3
4
5
6
7
8
7
abba
summuus
xabba
xabbay
comcom
comwwmoc
comwwtmoc
출력
1
2
3
4
5
6
7
0
1
1
2
2
0
1
코드(파이썬)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import sys
def palindrome(start, end, count):
while end-start > 0:
if line[start] != line[end]:
if count <= 1:
count += min(palindrome(start+1, end, count+1), palindrome(start, end-1, count+1))
break
start += 1
end -= 1
return count
t = int(sys.stdin.readline())
for _ in range(t):
line = sys.stdin.readline().rstrip()
print(min(palindrome(0, len(line)-1, 0), 2))
특이사항
- 해결방법
- 함수를 활용해 양쪽에서 다가오는 투포인터
- 내 코드(30,840KB, 348ms)에 비해 우수한 코드(바로가기, 30,840KB, 260ms)와 비교
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
from sys import stdin input = stdin.readline T = int(input()) def isPal(S): left = 0 right = len(S)-1 while left < right: if S[left] == S[right]: left += 1 right -= 1 else: return min(isPseudo(S, left+1, right), isPseudo(S, left, right-1)) return 0 def isPseudo(S, left, right): while left < right: if S[left] == S[right]: left += 1 right -= 1 else: return 2 return 1 for _ in range(T): print(isPal(input().rstrip()))
- 회문 → 유사회문 판단
- 기존: 1개의 함수에서 break로 중지
- 개선: 2개의 함수에서 return으로 중지
참고문헌
-
Comments powered by Disqus.