문제출처:
https://www.acmicpc.net/problem/14502
풀이
제 코드의 실행시간이 잘 푸신분들에 비해 최대 6배 차이가량납니다. 이해가 어려워서 이 글을 보러오신거면 제 코드를 보고 다른 빠른풀이법을 보시면좋을것같아요.(그분들 코드가 많이 어렵더라구요..)
제 코드상에서 실행시간을 줄일 수 있을만한 요소에 대해 알고계신분들은 댓글로 지적좀해주세요..
대충 머릿속으로는 구상이되는데 막상 구현할때 벽3개를놓고 연산하는 시뮬레이션과정이 너무어려워서 다른분들의 코드를 조금 참조했습니다...
백트래킹 기법도 쓰이는데, 제 생각에 dfs,bfs문제중에 어려운문제는 거의 백트래킹+브루트포스+dfs or bfs 같네요.. 어렵습니다.
글로써봤자 이해가 안가니 주석과 코드를 보고 흐름을 따라가보시면 이해가편할 것 같습니다.
#include<iostream> #include<algorithm> #include<queue> using namespace std; //벽을 세움 //벽3개를세움 //벽3개를 세울 때 bfs, //그 bfs를돌렷을때 각 최댓값비교 int map[8][8]; int temp[8][8]; int dx[4] = { 0,0,1,-1 }; int dy[4] = { -1,1,0,0 }; int n, m, area; void make_wall(int wall); void bfs(); int main() { cin.tie(0); cin.sync_with_stdio(false); cin >> n >> m; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cin >> map[i][j]; //비어있는공간있을떄 그떄 temp로복사받음 //비어있는 공간,그 자리에서부터 벽3개를 놓는 시늉을 다 돌림 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 0) { for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) temp[i][j] = map[i][j]; //현재 자리에 벽세움 temp[i][j] = 1; make_wall(1); //다시원상복구 temp[i][j] = 0; } } } cout << area << '\n'; } void make_wall(int wall) { //벽3개 만들었으면 bfs돌림 if (wall == 3) { bfs(); return; } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { //좌표가 0이면 if (temp[i][j] == 0) { //벽을 세우고 temp[i][j] = 1; //벽을 한칸늘렸으니 3개인지확인 make_wall(wall + 1); //위의함수로 그자리에서 모든연산끝났으니 다시 0으로, temp[i][j] = 0; } } } } void bfs() { //temp변수로 갖고놀면 virus가 퍼질떄 temp가 수정되므로 다시 배열복사 int virus[8][8]; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) virus[i][j] = temp[i][j]; queue<pair<int, int>>q; //바이러스좌표를 저장하여 퍼뜨림 for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (virus[i][j] == 2) q.push({ i,j }); //퍼뜨려서, //최종적으로 map에서 0인 현재좌표에서 //벽3개를 가정하고, 퍼뜨렸을 때 최대안전영역구함 while (!q.empty()) { int y = q.front().first; int x = q.front().second; q.pop(); for (int i = 0; i < 4; i++) { int ny = y + dy[i]; int nx = x + dx[i]; if (nx >= 0 && ny >= 0 && nx < m && ny < n) { if (virus[ny][nx] == 0 ) { virus[ny][nx] = 2; q.push({ ny,nx }); } } } } //최대영역구하기 int cnt = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (virus[i][j] == 0) cnt++; } } area = max(area, cnt); }
결과
'문제풀이(BOJ) > DFS,BFS' 카테고리의 다른 글
[백준] 촌수계산 (0) | 2020.01.20 |
---|---|
[백준 2589] 보물섬(BFS) (0) | 2020.01.17 |
[백준 2667] 단지번호붙이기 (BFS) (0) | 2020.01.17 |
[백준 11724] 연결 요소의 개수(DFS) (0) | 2020.01.15 |
[백준 1012] 유기농 배추 (DFS) (0) | 2020.01.15 |