BOJ 10942 - 팰린드롬? 문제풀이
문제를 읽고 이해하기
명우는 홍준이와 함께 팰린드롬 놀이를 해보려고 한다.
먼저, 홍준이는 자연수 N개를 칠판에 적는다. 그 다음, 명우에게 질문을 총 M번 한다.
각 질문은 두 정수 S와 E(1 ≤ S ≤ E ≤ N)로 나타낼 수 있으며, S번째 수부터 E번째 까지 수가 팰린드롬을 이루는지를 물어보며, 명우는 각 질문에 대해 팰린드롬이다 또는 아니다를 말해야 한다.
예를 들어, 홍준이가 칠판에 적은 수가 1, 2, 1, 3, 1, 2, 1라고 하자.
- S = 1, E = 3인 경우 1, 2, 1은 팰린드롬이다.
- S = 2, E = 5인 경우 2, 1, 3, 1은 팰린드롬이 아니다.
- S = 3, E = 3인 경우 1은 팰린드롬이다.
- S = 5, E = 7인 경우 1, 2, 1은 팰린드롬이다.
자연수 N개와 질문 M개가 모두 주어졌을 때, 명우의 대답을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수열의 크기 N (1 ≤ N ≤ 2,000)이 주어진다.
둘째 줄에는 홍준이가 칠판에 적은 수 N개가 순서대로 주어진다. 칠판에 적은 수는 100,000보다 작거나 같은 자연수이다.
셋째 줄에는 홍준이가 한 질문의 개수 M (1 ≤ M ≤ 1,000,000)이 주어진다.
넷째 줄부터 M개의 줄에는 홍준이가 명우에게 한 질문 S와 E가 한 줄에 하나씩 주어진다.
출력
총 M개의 줄에 걸쳐 홍준이의 질문에 대한 명우의 답을 입력으로 주어진 순서에 따라서 출력한다. 팰린드롬인 경우에는 1, 아닌 경우에는 0을 출력한다.
재정의와 추상화
지금까지의 DP는 입력을 먼저 받은 후, 그 입력받은 수들에 대해서 DP를 진행했다면, 이 문제에서는 입력 하나가 들어올 때마다 DP 처리를 해주는 방식으로 한다.
입력받은 수는 0번째 인덱스(i)부터 n - 1번째 인덱스까지 arr[i]에 저장한다. 입력이 들어올 때마다, 아래와 같은 알고리즘을 시행한다.
- i번째부터 i번째 범위의 수들은 Palindrome이다. -> isPalindrome[i][i] = true (자기 자신밖에 없으므로)
- i 인덱스 이전의 수 k에 대해서 arr[k] == arr[i]일 때 (두 수가 같을 때), Palindrome[k][i]가 true인지 false인지 결정하려고 한다.
- k - 1 인덱스부터 i - 1 인덱스까지의 수가 Palindrome이면 arr[k] == arr[i]인 k와 i에 대해서, k 인덱스부터 i 인덱스까지의 수도 Palindorme이다.
- 만약 i - k가 2 이하의 수면 arr[k] == arr[i]인 k와 i에 대해서, k 인덱스부터 i 인덱스까지의 수는 항상 Palindrome이다.
(예: 1 2 1 -> Palindrome, 1 1 -> Palindrome)
이렇게 isPalindrome을 모두 구한 뒤, 입력받은 s와 e에 대해 isPalindrome[s - 1][e - 1]을 출력하면 된다.
코드 작성
#include <iostream>
using namespace std;
int arr[2000];
bool isPalindrome[2000][2000];
int main() {
cin.sync_with_stdio(false);
cin.tie(NULL);
int n, m;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> arr[i];
isPalindrome[i][i] = true;
for (int k = i - 1; k >= 0; k--) {
if (arr[k] == arr[i]) {
if (i - k > 2) {
if (!isPalindrome[k + 1][i - 1]) continue;
}
isPalindrome[k][i] = true;
}
}
}
cin >> m;
while (m--) {
int s, e;
cin >> s >> e;
cout << isPalindrome[s - 1][e - 1] << '\n';
}
return 0;
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
BOJ 1202 - 보석 도둑 문제풀이 (0) | 2020.04.20 |
---|---|
BOJ 2003 - 수들의 합 2 문제풀이 (0) | 2020.04.19 |
BOJ 1806 - 부분합 문제풀이 (0) | 2020.04.19 |
BOJ 12015 - 가장 긴 증가하는 부분 수열 2 문제풀이 (0) | 2020.04.19 |
BOJ 1074 - Z 문제풀이 (0) | 2020.04.18 |
댓글
이 글 공유하기
다른 글
-
BOJ 1202 - 보석 도둑 문제풀이
BOJ 1202 - 보석 도둑 문제풀이
2020.04.20 -
BOJ 2003 - 수들의 합 2 문제풀이
BOJ 2003 - 수들의 합 2 문제풀이
2020.04.19 -
BOJ 1806 - 부분합 문제풀이
BOJ 1806 - 부분합 문제풀이
2020.04.19 -
BOJ 12015 - 가장 긴 증가하는 부분 수열 2 문제풀이
BOJ 12015 - 가장 긴 증가하는 부분 수열 2 문제풀이
2020.04.19