문제: https://www.acmicpc.net/problem/1028
memoization 과 현재 최대값보다 작은 다이아몬드는 계산하지 않는 가지치기 방법으로 시간 복잡도를 줄여 풀었습니다.
my solving
c++
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <fstream> #include <iostream> #include <cstring> #include <climits> #include <algorithm> #include <string> using namespace std; namespace Dir { enum Dir { southeast, southwest, northwest, northeast }; } const int MAX_N = 750; int height, width; int map[MAX_N + 1][MAX_N + 1]; int cache[MAX_N + 1][MAX_N + 1][4]; void getMovingPoint(Dir::Dir dir, int& y, int& x, int step) { if (step <= 0) return; switch (dir) { case Dir::southeast: y += step; x += step; break; case Dir::southwest: y += step; x -= step; break; case Dir::northwest: y -= step; x -= step; break; case Dir::northeast: y -= step; x += step; break; default: break; } } int getMaxMovingStep(Dir::Dir dir, int y, int x) { int& step = cache[y][x][dir]; if (step != -1) return step; step = 0; int nextY = y; int nextX = x; while (true) { switch (dir) { case Dir::southeast: nextY++; nextX++; break; case Dir::southwest: nextY++; nextX--; break; case Dir::northwest: nextY--; nextX--; break; case Dir::northeast: nextY--; nextX++; break; default: break; } if (nextY < 0 || nextY >= height || nextX < 0 || nextX >= width) break; if (map[nextY][nextX] != 1) break; else step++; } return step; } bool isDiamond(int y, int x, int step) { getMovingPoint(Dir::southeast, y, x, step); if (getMaxMovingStep(Dir::southwest, y, x) < step) return false; getMovingPoint(Dir::southwest, y, x, step); if (getMaxMovingStep(Dir::northwest, y, x) < step) return false; getMovingPoint(Dir::northwest, y, x, step); if (getMaxMovingStep(Dir::northeast, y, x) < step) return false; else return true; } int getMaxDiamond() { int ret = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (map[y][x] == 1) { if (ret == 0) ret++; int step = getMaxMovingStep(Dir::southeast, y, x); for (int i = step; step > ret - 1; step--) { if (isDiamond(y, x, step)) ret = step + 1; } } } } return ret; } int main() { memset(cache, -1, sizeof(cache)); memset(map, -1, sizeof(map)); cin >> height >> width; for (int i = 0; i < height; i++) { string str; cin >> str; for (int j = 0; j < width; j++) map[i][j] = str[j] - '0'; } cout << getMaxDiamond() << endl; return 0; } | cs |
'Algorithm, Data structure > Solved Algorithmic Problem' 카테고리의 다른 글
BAEKJOON 1032 - 명령 프롬프트 (0) | 2016.09.29 |
---|---|
BAEKJOON 1030 - 프렉탈 평면 (0) | 2016.08.13 |
BAEKJOON 1027 - 고층 건물 (0) | 2016.08.10 |
BAEKJOON 1026 - 보물 (0) | 2016.08.09 |
BAEKJOON 1024 - 수열의 합 (0) | 2016.08.08 |