[백준] 10942 팰린드롬? - python 파이썬

2025. 3. 6. 17:25·코딩테스트/백준

문제

 

팰린드롬이란?

앞에서 부터 읽을 때랑 끝에서 부터 읽을때 똑같은 것 , 회문

 

 

 

 

이 문제는 시간을 최대한 최적화하는게 관건인 문제이다. 

범위를 보면 알겠지만 N의 범위는 2000인 반면에 M의 범위가 100만으로 굉장히 큰편이다.

 

 

그래서 100만번 동안 2000개를 확인하면 무조건 시간초과가 나기때문에 어떻게 처리를 해야할지 머리가 아팠던 문제이다..

 

하지만 생각의 전환을 해서  미리 최대 길이 2000의 배열에서 발생할 수 있는 부분배열을 전부 확인해두면 시간 복잡도가 100만번 * 2000이 아니라 2000개를 확인  + 100만이 되므로 시간을 줄일 수 있다.

 

 

그러면 어떻게 모든 부분배열의 경우의 수를 구하는가?

 

 

바로 dp 를 통해서 전부 확인해주면 된다.

 

dp[s][e]가 1이면 s,e 구간이 팰린드롬을 만족하도록 구현해주면된다.

 

일단 dp란 복잡한 문제를 작은 문제로 바꾸어주는 문제이기때문에 작은 것부터 생각해보면 된다.

 

1. s == e일때  즉, 길이가 1인 부분배열

 

 

이때는 무조건 팰린드롬을 만족하므로 1 을 넣어준다

dp = [[0]*n for _ in range(n)]
#길이가 1인 부분배열 처리
for i in range(n):
    dp[i][i] = 1

 

 

2. e-s = 1 즉, 길이가 2인 부분배열

 

이때는 둘이 같아야지만 팰린드롬을 만족한다 ex) 11,22,33...

#길이가 2인 부분배열 처리
for i in range(n-1):
    if nums[i] == nums[i+1]:
        dp[i][i+1] = 1

 

 

그리고 중요한 길이가 3이상인 부분 배열

 

길이가 3이상인 부분배열이 팰린드롬을 만족할라면 s와e 사이에 있는 s-1 ~ e-1 구간의 부분배열이 팰린드롬을 만족해주어야한다. 그리고 s랑 e가 같아야지 s ~ e구간의 부분배열이 팰린드롬을 만족하는게 된다.

 

#cnt + 3 = 현재 확인하는 부분 배열의 길이
for cnt in range(n-2):
    for i in range(n-2-cnt):
        #i가 현재 확인하는 부분배열의 시작점 j는 끝점
        j = i+2+cnt
        if nums[i] == nums[j] and dp[i+1][j-1] == 1:
            dp[i][j] = 1

 

 

이때 for문의 범위를 잡는게 어려웠는데 쉽게 말하자면

 

 

 

cnt가 현재 고려하는 부분 문자열의 길이를 조절하는 역할을 한다.

  • cnt = 0이면 길이가 3짜리 (j = i + 2)
  • cnt = 1이면 길이가 4짜리 (j = i + 3)
  • cnt = 2이면 길이가 5짜리 (j = i + 4)

이후 m번의 질문마다 dp[s-1][e-1] 를 그대로 print해주면 된다. (인덱스값보다 1씩 큰 값이 대입됨)

 

 

정답코드

import sys
input = sys.stdin.readline
n = int(input())


nums = list(map(int,input().split()))

dp = [[0]*n for _ in range(n)]
#길이가 1인 부분배열 처리
for i in range(n):
    dp[i][i] = 1
#길이가 2인 부분배열 처리
for i in range(n-1):
    if nums[i] == nums[i+1]:
        dp[i][i+1] = 1

#cnt + 3 = 현재 확인하는 부분 배열의 길이
for cnt in range(n-2):
    for i in range(n-2-cnt):
        #i가 현재 확인하는 부분배열의 시작점 j는 끝점
        j = i+2+cnt
        if nums[i] == nums[j] and dp[i+1][j-1] == 1:
            dp[i][j] = 1

m = int(input())
for _ in range(m):
    s,e = map(int,input().split())
    print(dp[s-1][e-1])

 

 

 

덧붙이자면 input을 그대로 사용하면 시간초과가 난다... 이게 더 오래걸리는 건 알고있지만 정답이 잘 나오길래 그냥 썼었는데 앞으로 잘 변환해주어야겠다.

'코딩테스트 > 백준' 카테고리의 다른 글

[백준] 1744번 수 묶기 - python 파이썬  (0) 2025.03.20
[백준] 7663번 이중 우선순위 큐 - python 파이썬  (0) 2025.03.18
[백준] 1043번 거짓말 - python 파이썬  (0) 2025.03.05
[백준] 2636번 치즈 - python 파이썬  (0) 2025.03.04
[백준] 1339번 단위수학 -python 파이썬  (0) 2025.03.04
'코딩테스트/백준' 카테고리의 다른 글
  • [백준] 1744번 수 묶기 - python 파이썬
  • [백준] 7663번 이중 우선순위 큐 - python 파이썬
  • [백준] 1043번 거짓말 - python 파이썬
  • [백준] 2636번 치즈 - python 파이썬
hiwon
hiwon
천천히 굴러가는 코딩일기
  • hiwon
    하이원의 코딩 일기
    hiwon
  • 전체
    오늘
    어제
    • 분류 전체보기 (83)
      • 프론트엔드 (0)
        • react (0)
      • 백엔드 (13)
        • node.js (1)
        • spring (6)
      • 코딩테스트 (57)
        • 백준 (41)
        • 프로그래머스 (15)
      • 프로디지털아카데미 (9)
        • 클라우드 (1)
        • JavaScript (1)
      • github (1)
      • AWS (2)
      • Infra (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백엔드
    백트래킹
    프로그래머스
    깃허브
    다익스트라
    python
    github
    IT기획
    코테
    코딩테스트
    K디지털트레이닝
    kdt교육
    투포인터
    알파코
    신한투자증권
    UnionFind
    bastion host
    Java
    그리디
    프로디지털아카데미
    AWS
    파이썬
    BFS
    MSA
    EC2
    알고리즘
    spring
    백준
    알파코캠퍼스
    프디아
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hiwon
[백준] 10942 팰린드롬? - python 파이썬
상단으로

티스토리툴바