Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Priority Queue
- 구현
- Algorithm
- 코테
- programmers
- BFS
- spring boot
- Bruth Force
- SQL
- CSV
- hash table
- 모의SW역량테스트
- Back tracking
- 알고리즘
- SWEA
- Vue.js
- 시뮬레이션
- 알고리듬
- Trie
- GitHub
- Linked list
- Data Structure
- gpdb
- django
- aws
- boj
- DFS
- JavaScript
- 코딩테스트
- Python
Archives
- Today
- Total
hotamul의 개발 이야기
[Algorithm][C++] BOJ 2234 성곽 본문
https://www.acmicpc.net/problem/2234
2234번: 성곽
첫째 줄에 두 정수 n, m이 주어진다. 다음 m개의 줄에는 n개의 정수로 벽에 대한 정보가 주어진다. 벽에 대한 정보는 한 정수로 주어지는데, 서쪽에 벽이 있을 때는 1을, 북쪽에 벽이 있을 때는 2를,
www.acmicpc.net
풀이 핵심
1. BloodFill 문제로 BFS를 이용해 구현
2. 값이 모두 true인 flag[4] 생성, 벽으로 막힌 곳 찾기 위해 다음과 같이 구현, false로 표시 된 방향으로는 탐색 하지 않음.
bool flag[4] = { 1,1,1,1 };
int tmp = map[cur.r][cur.c];
for (int i = 0; i < 4; i++) {
if (tmp % 2) {
flag[i] = false;
}
tmp /= 2;
}
3. check배열에 다음과 같이 표시

4. 각각의 방의 개수를 room 배열에 다음과 같이 저장 (마지막 방 번호 = 이 성의 방의 개수, 가장 넓은 방 탐색)

5. 방 번호를 입력한 check 배열 주변 탐색 (인접한 방 번호 nearing 배열로 기록)
6. 하나의 벽을 제거하고 가장 넓은 방 탐색
코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <queue>
using namespace std;
int R, C;
int map[50][50];
int check[50][50];
int room[2501];
bool nearing[2501][2501];
int rn;
struct pos { int r, c; };
const int dr[] = { 0,-1,0,1 };
const int dc[] = { -1,0,1,0 };
void InputData();
void BloodFill(int r, int c);
void Solve();
int main() {
InputData();
Solve();
return 0;
}
void InputData() {
scanf("%d %d", &C, &R);
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
scanf("%d", &map[i][j]);
}
}
}
void BloodFill(int r, int c) {
queue<pos> q;
int count = 0;
++rn;
q.push({ r,c });
check[r][c] = rn;
count++;
while (!q.empty()) {
pos cur = q.front();
q.pop();
bool flag[4] = { 1,1,1,1 };
int tmp = map[cur.r][cur.c];
for (int i = 0; i < 4; i++) {
if (tmp % 2) {
flag[i] = false;
}
tmp /= 2;
}
for (int i = 0; i < 4; i++) {
if (flag[i]) {
int nr = cur.r + dr[i];
int nc = cur.c + dc[i];
if (check[nr][nc]) continue;
q.push({ nr,nc });
check[nr][nc] = rn;
count++;
}
}
}
room[rn] = count;
}
void Solve() {
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (!check[i][j]) {
BloodFill(i, j);
}
}
}
int max = 0;
for (int i = 1; i <= rn; i++) {
if (room[i] > max) max = room[i];
}
for (int i = 1; i <= rn; i++) {
for (int r = 0; r < R; r++) {
for (int c = 0; c < C; c++) {
if (check[r][c] != i) continue;
for (int dir = 0; dir < 4; dir++) {
int nr = r + dr[dir];
int nc = c + dc[dir];
if (nr < 0 || nr >= R || nc < 0 || nc >= C) continue;
if (check[nr][nc] != i) {
nearing[i][check[nr][nc]] = true;
}
}
}
}
}
int plus_max = 0;
for (int i = 1; i <= rn; i++) {
for (int j = 1; j <= rn; j++) {
if (nearing[i][j]) {
int tmp_max = room[i] + room[j];
if (plus_max < tmp_max) plus_max = tmp_max;
}
}
}
printf("%d\n%d\n%d", rn, max, plus_max);
}
아쉬운 점
1. 계속 OutOfBound 에러가 나와서 당황했다. 방의 최대 개수가 50개라고 문제를 잘 못 읽어 room[51], nearing[51][51]로 배열 크기를 선언했기 때문이었다. 문제를 다시 읽어보니 가로 최대 50 세로 최대 50 이었다. 그래서 최대 방 생성 개수는 2500이므로 room[2501], nearing[2501][2501]로 수정했다.
'myt-algorithm-practice > Samsung SW Certi Adv' 카테고리의 다른 글
[Algorithm][C++] BOJ 3190 뱀 (0) | 2021.09.14 |
---|---|
[Algorithm][C++] BOJ 17143 낚시왕 (0) | 2021.09.13 |
[Algorithm][C++] BOJ 17144 미세먼지 안녕! (0) | 2021.09.09 |
[Algorithm][C++] BOJ 11048 이동하기 (0) | 2021.09.08 |
[Algorithm][C++] BOJ 16235 나무 제테크 (0) | 2021.09.08 |