▶문제설명
[SWEA] 4014. 활주로 건설
https://www.swexpertacademy.com/main/code/problem/problemSubmitHistory.do?contestProbId=AWIeW7FakkUDFAVH
▶Hint
땅의 높이들이 주어진다.
땅의 높이 차가 1인 경우에 경사로를 놓아 활주로를 연결할 수 있다.
경사로의 높이는 항상 1이며, 세로로 세울 수 없다.
단, 경사로의 길이 X가 주어지는데
활주로를 만드는 과정에서
경사로가 길어서 놓을 공간이 부족한 경우,
경사로가 겹쳐지게 놓이는 경우는 허용하지 않는다.
가로, 세로로 완성될 수 있는 활주로 라인의 개수를 구하는 문제다.
내리막길과 오르막길로 나누어서 생각하고
내리막길일때 경사로를 놓는 경우 그 위치를 체크해두고,
오르막길일때 경사로를 놓는 경우 이미 경사로가 놓여져 있지 않은지 확인하는 과정이 필요하다.
경사로는 겹쳐서 놓을 수 없기 때문이다.
▶Solution
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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<cstring> using namespace std; int N, X, answer; int map[20][20]; bool check[20][20]; void init() { scanf("%d %d", &N, &X); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { scanf("%d", &map[i][j]); } } answer = 0; } bool isAbleHD(int r, int c) { for (int i = 0; i < X; i++) { if (c + i == N || map[r][c] != map[r][c + i]) { return false; } } for (int i = 0; i < X; i++) check[r][c + i] = true; return true; } bool isAbleHA(int r, int c) { for (int i = 0; i < X; i++) { if (-1 == c - i || map[r][c] != map[r][c - i] || check[r][c - i] == true) { return false; } } return true; } bool isAbleVD(int r, int c) { for (int i = 0; i < X; i++) { if (r + i == N || map[r][c] != map[r + i][c]) { return false; } } for (int i = 0; i < X; i++) check[r + i][c] = true; return true; } bool isAbleVA(int r, int c) { for (int i = 0; i < X; i++) { if (-1 == r-i || map[r][c] != map[r - i][c] || check[r - i][c] == true) { return false; } } return true; } bool checkLineH(int r, int c) { if (c == N - 1) return true; if (map[r][c] == map[r][c + 1]) { return checkLineH(r, c + 1); } if (map[r][c] == map[r][c + 1] + 1 && isAbleHD(r, c + 1)) // 내리막길 { return checkLineH(r,c + X); } if (map[r][c] == map[r][c + 1] - 1 && isAbleHA(r, c)) // 오르막길 { return checkLineH(r,c + 1); } return false; } bool checkLineV(int r, int c) { if (r == N - 1) return true; if (map[r][c] == map[r + 1][c]) { return checkLineV(r + 1, c); } if (map[r][c] == map[r + 1][c] + 1 && isAbleVD(r + 1, c)) // 내리막길 { return checkLineV(r + X, c); } if (map[r][c] == map[r + 1][c] - 1 && isAbleVA(r, c)) // 오르막길 { return checkLineV(r + 1, c); } return false; } void solve() { //가로 memset(check, 0, sizeof(check)); for (int r = 0; r < N; r++) { if (checkLineH(r,0)) answer++; } //세로 memset(check, 0, sizeof(check)); for (int c = 0; c < N; c++) { if (checkLineV(0, c)) answer++; } } int main() { int T; scanf("%d", &T); for(int t = 1 ; t<=T ; t++) { init(); solve(); printf("#%d %d\n", t, answer); } return 0; } | cs |
'■ 알고리즘 문제 풀이 > SWEA' 카테고리의 다른 글
[SWEA] 1868. 파핑파핑 지뢰찾기 (0) | 2019.03.15 |
---|---|
[SWEA] 5644. 무선 충전 (0) | 2019.03.06 |
[SWEA] 6808. 규영이와 인영이의 카드게임 (0) | 2019.03.02 |
[SWEA] 5653. 줄기세포배양 (0) | 2019.02.26 |
[SWEA-D3] 1213. String (0) | 2019.02.20 |