diff --git a/kangrae-jo/BFS/32-kangrae-jo.cpp b/kangrae-jo/BFS/32-kangrae-jo.cpp new file mode 100644 index 0000000..0943b52 --- /dev/null +++ b/kangrae-jo/BFS/32-kangrae-jo.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include + +using namespace std; + +const int EMPTY = 0; +const int BLOCK = 1; +const int OFFSET[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + +int N, id = 2; + +// 조각 번호 -> 블럭을 이루는 모든 {y,x} * rotate 4개 +unordered_map>>> um; +vector>> emptys; + +bool isIn(int y, int x) { return 0 <= y && y < N && 0 <= x && x < N; } + +vector> rotate(vector>& table) { + vector> rotated(N, vector(N)); + for (int y = 0; y < N; y++) { + for (int x = 0; x < N; x++) { + rotated[x][N - 1 - y] = table[y][x]; + } + } + return rotated; +} + +void checkBlock(vector>& table, int y, int x, int id, int rot, int target, vector>& visited) { + queue> q; + q.push({y, x}); + visited[y][x] = true; + + while (!q.empty()) { + auto[curY, curX] = q.front(); + q.pop(); + + um[id][rot].push_back({curY - y, curX - x}); + + for (int dir = 0; dir < 4; dir++) { + int nextY = curY + OFFSET[dir][0]; + int nextX = curX + OFFSET[dir][1]; + if (isIn(nextY, nextX) && table[nextY][nextX] == target && !visited[nextY][nextX]) { + q.push({nextY, nextX}); + visited[nextY][nextX] = true; + } + } + } + sort(um[id][rot].begin(), um[id][rot].end()); +} + +void checkBlock(vector>& table, int y, int x, int id, int rot) { + queue> q; + q.push({y, x}); + table[y][x] = id; + + while (!q.empty()) { + auto[curY, curX] = q.front(); + q.pop(); + + um[id][rot].push_back({curY - y, curX - x}); + + for (int dir = 0; dir < 4; dir++) { + int nextY = curY + OFFSET[dir][0]; + int nextX = curX + OFFSET[dir][1]; + if (isIn(nextY, nextX) && table[nextY][nextX] == BLOCK) { + q.push({nextY, nextX}); + table[nextY][nextX] = id; + } + } + } + sort(um[id][rot].begin(), um[id][rot].end()); +} + +void makeBlocks(vector>& table, int rot) { + for (int y = 0; y < N; y++) { + for (int x = 0; x < N; x++) { + if (table[y][x] == BLOCK) { + checkBlock(table, y, x, id, rot); + id++; + } + } + } +} + +void makeBlocks_(vector>& table, int rot) { + vector> visited(N, vector(N, false)); + for (int y = 0; y < N; y++) { + for (int x = 0; x < N; x++) { + if (table[y][x] >= 2 && !visited[y][x]) { + checkBlock(table, y, x, table[y][x], rot, table[y][x], visited); + } + } + } +} + +void checkEmpty(vector>& board, int y, int x) { + queue> q; + q.push({y, x}); + board[y][x]++; + + vector> temp; + while (!q.empty()) { + auto[curY, curX] = q.front(); + q.pop(); + + temp.push_back({curY - y, curX - x}); + + for (int dir = 0; dir < 4; dir++) { + int nextY = curY + OFFSET[dir][0]; + int nextX = curX + OFFSET[dir][1]; + if (isIn(nextY, nextX) && board[nextY][nextX] == EMPTY) { + q.push({nextY, nextX}); + board[nextY][nextX]++; + } + } + } + sort(temp.begin(), temp.end()); + emptys.push_back(temp); +} + +void makeEmptys(vector>& board) { + for (int y = 0; y < N; y++) { + for (int x = 0; x < N; x++) { + if (board[y][x] == EMPTY) { + checkEmpty(board, y, x); + } + } + } +} + +int solution(vector> board, vector> table) { + N = board.size(); + + makeBlocks(table, 0); + for (int rot = 1; rot < 4; rot++) { + table = rotate(table); + makeBlocks_(table, rot); + } + + makeEmptys(board); + + int answer = 0; + unordered_map used; + + for (vector>& empty : emptys) { + bool flag = false; + for (int i = 2; i < id; i++) { + if (used[i]) continue; + for (int rot = 0; rot < 4; rot++) { + if (empty == um[i][rot]) { + answer += empty.size(); + used[i] = true; + flag = true; + break; + } + } + if (flag) break; + } + } + + return answer; +} \ No newline at end of file diff --git a/kangrae-jo/README.md b/kangrae-jo/README.md index d9a3e9c..e70a2b0 100644 --- a/kangrae-jo/README.md +++ b/kangrae-jo/README.md @@ -32,4 +32,5 @@ | 28차시 | 2024.06.10 | BFS | [경주로 건설](https://school.programmers.co.kr/learn/courses/30/lessons/67259)|[#110](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/110)| | 29차시 | 2024.06.19 | TRIE | [[3차] 자동완성](https://school.programmers.co.kr/learn/courses/30/lessons/17685)|[#114](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/114)| | 30차시 | 2024.07.18 | BFS | [치즈](https://www.acmicpc.net/problem/2638)|[#117](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/117)| -| 31차시 | 2024.07.31 | Prefix Sum | [두 배열의 합](https://www.acmicpc.net/problem/2143)|[#122](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/122)| \ No newline at end of file +| 31차시 | 2024.07.31 | Prefix Sum | [두 배열의 합](https://www.acmicpc.net/problem/2143)|[#122](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/122)| +| 32차시 | 2024.08.10 | BFS | [퍼즐 조각 채우기](https://school.programmers.co.kr/learn/courses/30/lessons/84021)|[#130](https://github.com/AlgoLeadMe/AlgoLeadMe-12/pull/130)|