ALGOSPOT PI 알고스팟 파이
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #include<iostream> #include <cstdio> #include <cmath> #include<vector> #include<string> #include<cstring> #include <algorithm> using namespace std; const int INF = 987654321; string N; int cache[10002]; //N[a...b] 구간의 난이도를 반환한다. int levelPI(int a,int b) { //a~b까지 숫자 조각을 가져온다. string M = N.substr(a, b-a + 1); //첫 글자만으로 이루어진 문자열과 같으면 난이도는 1 if (M == string(M.size(), M[0])) return 1; //등차수열인지 검사한다. bool progressive = true; for (int i = 0; i < M.size() - 1; i++) if (M[i + 1] - M[i] != M[1] - M[0]) progressive = false; //등차수열이고 공차가 1 혹은 -1이면 난이도는 2 if (progressive &&abs(M[1] - M[0]) == 1) return 2; //두 수가 번갈아 등장하는지 확인한다. bool alternating = true; for (int i = 0; i < M.size(); i++) if (M[i] != M[i % 2]) alternating = false; if (alternating) return 4; if (progressive) return 5; return 10; } //수열 N[begin....]를 외우는 방법 중 난이도의 최소 합을 출력한다. int memorize(int begin) { //기저 사례:수열의 끝에 도달했을 경우 if (begin == N.size()) return 0; //메모제이션 int &ret = cache[begin]; if (ret != -1) return ret; ret = INF; for (int L = 3; L <= 5; L++) if (begin + L <= N.size()) ret = min(ret, memorize(begin + L) + levelPI(begin, begin + L - 1)); return ret; } int main(void) { ios_base::sync_with_stdio(0); cin.tie(0); int cases; cin >> cases; while (cases--) { memset(cache, -1, sizeof(cache)); cin >> N; cout << memorize(0) << "\n"; } return 0; } | cs |
문제 출처:https://algospot.com/judge/problem/read/PI
조각의 난이도를 판정하는 것은 번거롭지만 생각보다 쉬운 편이였습니다.(물론 그것도 못했지만)
'알고리즘 > 알고리즘 문제 해결전략(종만북)' 카테고리의 다른 글
ALGOSPOT LUNCHBOX 알고스팟 도시락 데우기 (0) | 2019.01.23 |
---|---|
ALGOSPOT MATCHORDER 알고스팟 출전 순서 정하기 (0) | 2019.01.23 |
ALGOSPOT JLIS 알고스팟 합친 LIS (0) | 2019.01.23 |
ALGOSPOT LIS 알고스팟 최대 증가 부분 수열 (0) | 2019.01.22 |
ALGOSPOT TRIANGLEPATH 알고스팟 삼각형 위의 최대 경로 (0) | 2019.01.22 |