오답 여부: o

편집 시간: 2022년 3월 15일 오후 2:35

코드

Algorithm/10942.py at main · Junroot/Algorithm

풀이

질문의 개수가 최대 1,000,000개이므로 질문하는 순간 팰린드롬을 계산하면 시간 초과가 발생한다는 것을 알 수 있다. 그러면 미리 팰린드롬을 계산해둬야 되는데 수열의 크기가 최대 2,000이므로 O(N^2)내로 해결해야된다.

어떤 팰린드롬이 있을 때 이 수열의 왼쪽, 오른쪽에 같은 수를 붙이면 계속 팰린드롬이라는 성질을 이용해 문제를 접근했다.

잘못된 풀이

나는 위의 성질을 이용해서 길이가 1, 2인 팰린드롬들을 구하고 이 팰린드롬에서 왼쪽과 오른쪽을 늘리면서 구할 수 있는 모든 팰린드롬을 구했다. 아래 코드가 그 과정이다. 하지만 union에서 시간이 많이 발생하는지 시간 초과가 발생했다.

from collections import deque
from sys import stdin

n = int(input())
numbers = list(map(int, input().split()))
new_ranges = deque([(i, i) for i in range(n)]) # 길이가 1인 수열은 모드 팰린드롬이다.


for i in range(n - 1):
    if numbers[i] == numbers[i + 1]:
        new_ranges.append((i, i + 1))

ranges = set()
for _ in range(n // 2):
    ranges = ranges.union(new_ranges)
    for _ in range(len(new_ranges)):
        start, end = new_ranges.popleft()
        if start == 0 or end == n - 1:
            continue
        if numbers[start - 1] == numbers[end + 1]:
            new_ranges.append((start - 1, end + 1))

m = int(input())

for _ in range(m):
    start, end = map(int, stdin.readline().split())
    if (start - 1, end - 1) in ranges:
        print("1")
    else:
        print("0")

맞는 풀이

결국 다른 사람 풀이를 조금 참고했다. 기본적인 알고리즘은 같았는데, 이중 배열을 사용해서 팰린드롬을 관리했다. palindromes[start][end]는 start부터 end까지의 수열이 팰린드롬이면 1, 아니면 0을 나타내고 있다. palindromes[start][end] 값을 구할 때, palindromes[start-1][end+1] 이 필요하므로, 길이가 작은 수열을 우선적으로 계산하는 식으로 구현했다.

from sys import stdin

n = int(input())
numbers = list(map(int, input().split()))
palindromes = [[0 for _ in range(n)] for _ in range(n)]

for i in range(n):
    palindromes[i][i] = 1

for i in range(n - 1):
    if numbers[i] == numbers[i + 1]:
        palindromes[i][i + 1] = 1

for length in range(3, n + 1):
    for i in range(n - length + 1):
        start = i
        end = i + length - 1
        if numbers[start] == numbers[end] and palindromes[start + 1][end - 1] == 1:
            palindromes[start][end] = 1

m = int(input())

for _ in range(m):
    start, end = map(int, stdin.readline().split())
    print(palindromes[start - 1][end - 1])