https://www.acmicpc.net/problem/10942
10942번: 팰린드롬?
총 M개의 줄에 걸쳐 홍준이의 질문에 대한 명우의 답을 입력으로 주어진 순서에 따라서 출력한다. 팰린드롬인 경우에는 1, 아닌 경우에는 0을 출력한다.
www.acmicpc.net
문제 분석
팰린드롬(palindrome)이란?
회문 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 회문(回文) 또는 팰린드롬(palindrome)은 거꾸로 읽어도 제대로 읽는 것과 같은 문장이나 낱말, 숫자, 문자열(sequence of characters) 등이다. 보통 낱말 사이에 있는 띄
ko.wikipedia.org
문제는 N개의 자연수 중 S번째 수부터 E번째까지의 수가 팰린드롬인지 판단하는 문제이다.
질문의 개수가 백만 개이며 팰린드롬을 백만 번 판단하게 된다면 문제의 시간제한인 0.5초를 넘어 시간 초과가 나오게 된다.
따라서 팰린드롬을 판단하는 것을 N개의 자연수가 입력되었을 때 바로 모든 경우의 수를 판단하고
질문을 받았을 때 바로 출력할 수 있도록 해야 한다.
우선, 질문을 받았을 때 판단해야 되는 수의 개수가 홀수인지 짝수인지 판단이 필요하다.
만약 홀수라면 가운데 수를 기준으로 양쪽이 같아야 하고, 짝수라면 반을 나누어 양쪽을 비교해야 한다.
어떻게 하면 모든 경우의 수를 판단할 수 있을까?
기준점이 필요하다.
N개의 자연수를 모두 기준으로 생각하고 양쪽을 하나씩 추가하면서 날개를 펼치듯 수를 늘려가며 판단하면 모든 경우를 판단할 수 있다.
7개의 수가 주어졌다고 가정하면 1번부터 기준을 잡는다.
1. 판단해야 되는 수의 개수가 홀수일 때
1. 1. 첫 번째 수, 마지막 번째 수를 기준으로 했을 때
모든 경우 중 숫자를 하나만 갖는 경우는 모두 팰린드롬이다.
즉, s = 1, e = 1일 경우 팰린드롬이 된다.
이제 양쪽을 펼치며 판단을 해야 한다.
하지만 첫 번째 수보다 앞에 있는 수가 없기 때문에 판단이 불가능하다. (인덱스의 범위를 넘어간 경우)
이런 경우 바로 함수를 종료한다.
1. 2. 첫 번째 수가 기준이 아닐 경우
만약 세 번째 수가 기준이라고 했을 때
첫 번째 경우와 같이 한 개를 판단하는 경우는 팰린드롬이므로 생략하고
양 쪽에 수를 하나씩 늘려 추가한다.
즉, s = 2, e = 4가 된다. 이 경우 팰린드롬이 아닌 경우라고 저장하면 된다.
이렇게 양쪽으로 수를 하나씩 늘려가며 판단해 s, e를 인덱스로 갖는 이차원 리스트에 팰린드롬 여부를 저장한다.
2. 판단해야 되는 수의 개수가 짝수일 때
2. 1. 첫 번째 수, 마지막 번째 수를 기준으로 했을 때
만약 판단해야 되는 수의 개수가 짝수라면 기준에서 바로 다음의 수를 같이 기준으로 정해 같은 방식으로 진행한다.
즉, 기준이 첫 번째 수와 두 번째 수가 되는 것이다.
2. 2. 첫 번째 수가 기준이 아닐 경우
위와 같이 세 번째 수가 기준이라면 세 번째, 네 번째 수가 기준이 되고
s = 2, e = 5 ... 와 같이 수를 판단할 수 있다.
위의 방식을 진행하면 모든 경우의 팰린드롬 여부를 확인할 수 있다.
팰린드롬 여부는 dp[s - 1][e - 1]로 이차원 배열에 저장하면 된다. (인덱스는 0부터이므로 1씩 빼주어야 함)
def pelCheck(start, end):
while start > -1 and end < n:
if arr[start] == arr[end]:
pel[start][end] = 1
else:
break
start -= 1
end += 1
...
for i in range(n):
# 판단 수가 홀수 개일 때
pelCheck(i, i)
# 판단 수가 짝수 개일 때
pelCheck(i, i + 1)
...
코드
import sys
input = sys.stdin.readline
def pelCheck(start, end):
while start > -1 and end < n:
if arr[start] == arr[end]:
pel[start][end] = 1
else:
break
start -= 1
end += 1
n = int(input())
arr = list(map(int, input().split()))
pel = [[0 for _ in range(n)] for _ in range(n)]
for i in range(n):
pelCheck(i, i)
pelCheck(i, i + 1)
m = int(input())
for _ in range(m):
s, e = map(int, input().split())
print(pel[s - 1][e - 1])
'알고리즘 > 백준' 카테고리의 다른 글
[백준/Python] 1402번: 아무래도이문제는A번난이도인것같다 (0) | 2023.02.24 |
---|---|
[백준/Python] 17404번: RGB거리 2 (0) | 2023.02.08 |
[백준/Python] 1958번: LCS 3 (0) | 2023.01.31 |
[백준/Python] 2961번: 도영이가 만든 맛있는 음식 (0) | 2023.01.30 |
[백준/Python] 1205번: 등수 구하기 (0) | 2023.01.27 |