일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- PYTHON
- Git
- c++
- Django
- 장고
- java
- DRF
- 알고리즘
- web
- 알고리즘 연습
- 파이썬
- es6
- API
- 알고리즘 풀이
- MAC
- 알고리즘 문제
- AWS
- react
- HTML
- django rest framework
- Algorithm
- js
- 백준
- Baekjoon
- django ORM
- CSS
- javascript
- django widget
- form
- 파이썬 알고리즘
Archives
- Today
- Total
수학과의 좌충우돌 프로그래밍
[C++] BAEKJOON 10942 팰린드롬? 본문
https://www.acmicpc.net/problem/10942
일반적으로 팰린드롬을 판별하기 위해서는 맨 앞과 맨 뒤, 앞에서 두번째와 뒤에서 두번째 … 다음과 같이 비교해봐야 하므로 O(N)
의 시간복잡도가 걸립니다. 이 문제 같은 경우에는 질문이 M 개이므로 전체 시간복잡도는 O(MN)
이 됩니다. 이 때 M 의 범위가 1 ≤ M ≤ 1,000,000
이므로 시간초과에 걸리게 됩니다.
이를 해결하기 위해서 동적계획법 으로 접근하였습니다.
-
길이가 1 인 경우
길이가 1인 경우에는 앞에서 읽던 뒤에서 읽던 같으므로 항상 팰린드롬이 성립합니다.
-
길이가 2 인 경우
길이가 2인 경우에는 앞의 수와 뒤의 수가 같아야 팰린드롬이 성립합니다.
-
길이가 3 이상인 경우
길이가 3 이상인 경우에는 동적계획법을 사용하여 맨 앞과 맨 뒤의 일치여부 와 그 둘을 제외한 나머지 부분이 팰린드롬인지 확인합니다.
#include <iostream>
using namespace std;
int number[2001];
// i 번째 수부터 j 번째 수가 팰린드롬을 이루는지 여부
int dp[2001][2001];
int main() {
int N,M;
cin >> N;
for (int i=1;i<=N;i++){
cin >> number[i];
}
// 길이가 1일 때
for (int i=1;i<=N;i++){
dp[i][i] = 1;
}
// 길이가 2일 때
for (int i=1;i<=N-1;i++){
if (number[i]==number[i+1]) dp[i][i+1] = 1;
}
// 길이가 3 이상일 때
for (int k=3;k<=N;k++){
for(int i=1;i<=N-k+1;i++){
int j=i+k-1;
if (number[i]==number[j] && dp[i+1][j-1])
dp[i][j] = 1;
}
}
cin >> M;
for (int i=0;i<M;i++){
int start, end;
scanf("%d%d", &start, &end);
printf("%d\n", dp[start][end]);
}
return 0;
}
일반적으로 cin, cout 을 사용해 입출력을 제어하다가 마지막 부분에서는 scanf 와 printf 를 통해 입출력을 하였습니다. M 의 값이 굉장히 크므로 많은 입출력을 필요할 때는 둘의 시간 차이 때문에 시간초과가 나는 경우가 있으므로 조심하시길 바랍니다.
'알고리즘 > C++' 카테고리의 다른 글
[C++] BAEKJOON 2156 포도주 시식 (0) | 2019.09.06 |
---|---|
[C++] BAEKJOON 1509 팰린드롬 분할 (0) | 2019.09.06 |
[C++] BAEKJOON 1890번 점프 (0) | 2019.09.06 |
[C++] BAEKJOON 5052번 전화번호목록 (0) | 2019.08.26 |
[C++] BAEKJOON 8901번 화학제품(ACM-ICPC Daejeon 2011) (0) | 2019.08.02 |
Comments