Home 백준 17609번 회문
Post
Cancel

백준 17609번 회문

정보

문제 바로가기 [클릭]

난이도: 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으로 중지

참고문헌

-

This post is licensed under CC BY 4.0 by the author.

백준 2470번 두 용액

백준 2661번 좋은수열

Comments powered by Disqus.