[boj] 17609 회문

https://www.acmicpc.net/problem/17609

문제

회문(回文) 또는 팰린드롬(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

7
abba
summuus
xabba
xabbay
comcom
comwwmoc
comwwtmoc

예제 출력 1

0
1
1
2
2
0
1

풀이

회문(펠린드롬)인지 확인하는 것은 문자열을 앞에서부터 순회했을 때와 뒤에서부터 순회했을 때 일치하지 않는 부분이 없는지 확인하는 것으로 매우 간단하다. 문제를 풀 때 틀렸던 부분은 회문이 아닌 것이 판별된 인덱스의 문자열을 지우는 부분이었다.

  • 문자열 자르는 코드
      left = s[:removeAt]
      right = s[removeAt + 1 :] if removeAt < len(s) else len(s) - 1
      s = left + right
    
import sys

input = sys.stdin.readline
N = int(input())
strs = (input().rstrip() for _ in range(N))

def check(s, removeAt=None):
    """문자열 s에서 removeAt에 위치한 문자를 제거한 문자열이 회문인지 검사"""
    length = len(s)
    if removeAt != None:
        # removeAt에 위치한 문자 제거
        left = s[:removeAt]
        right = s[removeAt + 1 :] if removeAt < len(s) else len(s) - 1
        s = left + right
        length = len(s)

    # 회문 검사
    failedAt = None
    mid = (length // 2 - 1) + 1
    for i1 in range(mid):
        i2 = -1 * i1 - 1
        char1 = s[i1]
        char2 = s[i2]
        if char1 != char2:
            failedAt = i1
            break
    return failedAt

for s in strs:
    failedAt = check(s)
    if failedAt != None:
        if check(s, failedAt) != None:
            failedAt = len(s) + (-1 * failedAt - 1)
            if check(s, failedAt) != None:
                # 회문이 아님
                print(2)
                continue
        # 유사회문임
        print(1)
        continue
    else:
        # 회문
        print(0)
        continue