-
백준(BOJ) 2234번 성곽알고리즘 풀이/백준(Boj) 2019. 10. 5. 03:38
문제 : https://www.acmicpc.net/problem/2234
2234번: 성곽
문제 대략 위의 그림과 같이 생긴 성곽이 있다. 굵은 선은 벽을 나타내고, 점선은 벽이 없어서 지나다닐 수 있는 통로를 나타낸다. 이러한 형태의 성의 지도를 입력받아서 다음을 계산하는 프로그램을 작성하시오. 이 성에 있는 방의 개수 가장 넓은 방의 넓이 하나의 벽을 제거하여 얻을 수 있는 가장 넓은 방의 크기 위의 예에서는 방은 5개고, 가장 큰 방은 9개의 칸으로 이루어져 있으며, 위의 그림에서 화살표가 가리키는 벽을 제거하면 16인 크기의 방을 얻을
www.acmicpc.net
풀이 :
1번은 bfs를 돌때마다 num을 ++ 해주어서 구한다.
2번은 bfs를 돌며 q에 담긴 횟수를 반환하여 넓이 중 최대 값을 찾는다.
3번은 0 ,0 부터 m,n까지 돌면서 상하좌우로 인접한 방중 1. 서로 다른 방이면서 2. 벽으로 막혀있다면
그때 벽을 뚫고 합친 값을 저장한다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters#include <iostream> #include <queue> #include <algorithm> using namespace std; int n, m; int board[50][50]; int d[50][50]; int rooms[50 * 50]; // 서 북 동 남 const int dy[4] = { 0,-1,0,1 }; const int dx[4] = { -1,0,1,0}; int solve(int y, int x, int roomNum) { queue<pair<int, int>> q; q.push({ y,x }); d[y][x] = roomNum; int cnt = 0; while (!q.empty()) { y = q.front().first; x = q.front().second; // 방의 넓이 카운트 cnt++; q.pop(); for (int i = 0; i < 4; ++i) { int ny = y + dy[i]; int nx = x + dx[i]; // 범위 체크 if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; // 방문 체크 if (d[ny][nx] != 0) continue; // 벽 체크 if (board[y][x] & (1 << i)) continue; // ny,nx는 몇번방인지 d[ny][nx] = roomNum; q.push({ ny,nx }); } } return cnt; } int main() { cin >> n >> m; for(int i=0; i<m; ++i) for (int j = 0; j < n; ++j) { cin >> board[i][j]; } int num = 0; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) { if (d[i][j] == 0) { num++; // num번방의 넓이는 = solve(i,j,num); rooms[num] = solve(i, j, num); } } // 개수 출력 cout << num << "\n"; int ret = 0; // 가장 큰 넓이 구한다 for (int i = 1; i <= num; ++i) { ret = max(ret, rooms[i]); } cout << ret << "\n"; // d 에는 각 방의 번호가 적혀있고 // 합칠수있는 방이라면 합친후 최대값 계산 ret = 0; for(int i=0; i<m; ++i) for (int j = 0; j < n; ++j) { int y = i; int x = j; for (int k = 0; k < 4; ++k) { int ny = y + dy[k]; int nx = x + dx[k]; if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if (d[ny][nx] == d[y][x]) continue; // 벽일때 뿌수고 최대값 구해야한다. if (board[y][x] & (1 << k)) { ret = max(ret, rooms[d[ny][nx]] + rooms[d[y][x]]); } } } cout << ret << "\n"; return 0; } '알고리즘 풀이 > 백준(Boj)' 카테고리의 다른 글
백준(BOJ) 12996번 Acka (31) 2019.10.13 백준(BOJ) 15562 톱니바퀴(2) (31) 2019.10.10 백준(BOJ) 1600번 말이 되고픈 원숭이 (63) 2019.10.03 백준(BOJ) 14442번 벽 부수고 이동하기 2 (31) 2019.10.01 백준(BOJ) 12869번 뮤탈리스크 (31) 2019.09.28