본문 바로가기

백준/골드

[백준 10942번] 팰린드롬? (C++)

문제링크 : https://www.acmicpc.net/problem/10942

 

10942번: 팰린드롬?

총 M개의 줄에 걸쳐 홍준이의 질문에 대한 명우의 답을 입력으로 주어진 순서에 따라서 출력한다. 팰린드롬인 경우에는 1, 아닌 경우에는 0을 출력한다.

www.acmicpc.net

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;

int arr[2001];
int dp[2001][2001];

int main()
{
    ios_base::sync_with_stdio(0); 
	cin.tie(0);
    
    int N, M;
    cin >> N;
    for(int i=1; i<=N; i++)
    {
        cin >> arr[i];
        dp[i][i]=1; //1글자인 경우
        if(arr[i-1]==arr[i] && i>1) dp[i-1][i]=1; //2글자인 경우(11, 22 등)
    }


    for(int i=N-2; i>=1; i--) //3글자 이상인 경우
    {
        for(int j=i+2; j<=N; j++) 
        {
            if(arr[i]==arr[j] && dp[i+1][j-1]) dp[i][j]=1;
        }
    }

    cin >> M;
    while(M--)
    {
        int S, E;
        cin >> S >> E;
        cout << dp[S][E] <<"\n";
    }

    return 0;
}

dp의 응용문제이다.

먼저 고려해야할 경우의 수는 다음과 같이 3가지다.

<1글자>
dp[i][i]의 경우는 무조건 팰린드롬 수

<2글자>
연속해서 같은 경우는 팰린드롬 수 (11, 22와 같은 경우)

<3글자 이상>
각 위치 (i, j)의 값이 같은지와, (i+1, j-1)의 값이 펠린드롬수인지 확인 
해당 값이 펠린드롬 수라면 dp[i][j]도 펠린드롬 수
ex) 1 2 1 
2 -> dp[2][2]이므로 펠린드롬 수
i = 1, j = 3 -> dp[2][2]가 펠린드롬 수이고 arr[i]와 arr[j]의 값이 같으므로 dp[1][3]도 펠린드롬 수

3글자 이상인 경우가 다소 까다롭다.

2중 반복문을 통하여 구하였는데, i를 1부터 시작하면 다음과 같은 문제가 생긴다.

i=1, j=3인 경우 : dp[2][2]의 값을 알고 있으므로 현재 값도 판별가능 (가운데가 1글자)
i=1, j=4인 경우 : dp[2][3]의 값을 알고 있으므로 현재 값도 판별가능 (가운데가 2글자)
i=1, j=5인 경우 : dp[2][4]의 값을 모르므로 현재 값 판별 불가능 (가운데가 3글자)

이렇듯 가운데가 1~2글자 인 경우에는 사전에 1~2글자에 대해 팰린드롬 수 인지 판별하였으므로 현재 위치에 대해 팰린드롬 수인지 판별이 가능하지만, 가운데가 3글자 이상이면 해당 범위의 값이 팰린드롬 수인지 알 수가 없다.

 

따라서 i를 1부터 시작하는 것이 아닌 맨 뒤라고 할 수 있는 N-2부터 시작한다.

i=N-2부터 시작하고, j은 i+2부터 시작하므로 첫 탐색은 마지막 3자리에 대해 하게 된다.

이후에 계산하다보면 i=3, j=7과 같이 가운데가 3글자인 경우가 나온다.

하지만 i를 큰 값부터 시작하여 i--;로 탐색했기에 i-1, j+1에 해당하는 i=4, j=6의 값을 i=4일 때 이미 판별을 해놓은 상태이다.

따라서 i를 큰 값(뒤)부터 탐색한다면 이렇게 문제없이 이어서 판별해나갈 수 있다.

'백준 > 골드' 카테고리의 다른 글

[백준 1229번] 육각수 (C++)  (0) 2023.09.02
[백준 1759번] 암호 만들기 (C++)  (0) 2023.08.30
[백준 2467번] 용액 (C++)  (0) 2023.08.26
[백준 2166번] 다각형의 면적 (C++)  (0) 2023.08.25
[백준 1806번] 부분합 (C++)  (0) 2023.08.24