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
- DFS
- JavaScript
- boj
- 코테
- django
- 코딩테스트
- SWEA
- Bruth Force
- programmers
- 알고리즘
- Linked list
- gpdb
- 시뮬레이션
- Algorithm
- Priority Queue
- spring boot
- 모의SW역량테스트
- BFS
- Vue.js
- Trie
- hash table
- Python
- CSV
- 알고리듬
- SQL
- Back tracking
- GitHub
- aws
- 구현
- Data Structure
Archives
- Today
- Total
hotamul의 개발 이야기
[Algorithm][C++] JUNGOL 4198: swat. 산불 본문
myt-algorithm-practice/Samsung SW Certi Adv
[Algorithm][C++] JUNGOL 4198: swat. 산불
hotamul 2021. 11. 1. 00:11url: http://www.jungol.co.kr/bbs/board.php?bo_table=pbank&wr_id=3548&sca=99
JUNGOL
www.jungol.co.kr
풀이 핵심
1. Back Tracking / Bruth Force 문제 (Blood Fill 방법? 으로 구현)
2. 초기 불 (2) 의 위치 정보를 vector fire에 저장
3. 초기 safe zone (0) 위치 정보를 vector safe_zone에 저장
4. 재귀 함수 solve 구현.
- 전달 인자는 safe_zone vector의 index와 벽을 만든 횟 수 cnt.
- 현재 index가 가르키는 safe zone을 벽으로 만들 거나 만들지 않거나 (만들지 않을 경우 cnt 는 증가 시키지 않고 index 만 증가 시켜 solve 함수 재 실행)
- cnt가 3일 경우 fire_spread 함수 실행
- fire_spread 함수가 반환한 값이 ans 보다 크면 그 값을 ans에 대입한다.
5. fire_spread 함수는 큐를 이용해 불 (2)이 번질 수 있는 곳까지 모두 번지게 만드는 함수이다.
- 먼저 초기 safe zone의 개수 (safe_zone.size() - 3, -3을 해주는 이유는 3개를 벽으로 만들었기 때문) 를 fire_spread 함수가 return 할 ret 변수에 저장하고 큐를 생성한다. 중복 방문을 방지하기 위해 visit 함수를 만들고 0으로 초기화 한다.
- 기존에 불의 위치를 저장했던 fire vector의 값들을 큐에 push 한다
- 방문하지 않았고 (아직 불이 번지지 않았고) 배열의 크기를 넘지 않는 곳에 방문하게 되면 위치 정보를 큐에 담고 visit배열에 표시 (true) 한다. 그리고 ret 을 1 감소 시킨다.
- 큐를 모두 비우고 ret을 return 한다. (남아 있는 safe_zone 개수를 return 한다)
코드
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;
int N, M, ans;
int map[8][8];
struct POS {
int r, c;
};
vector<POS> fire; // 초기 불 위치 정보
vector<POS> safe_zone; // 초기 safe zone 위치 정보
const int dr[] = { 0,0,-1,1 };
const int dc[] = { 1,-1,0,0 };
inline int fire_spread() { // blood fill 방법으로 불 퍼지기
int ret = safe_zone.size() - 3;
queue<POS> q;
bool visit[8][8] = { 0, };
for (int i = 0; i < (int)fire.size(); i++) {
visit[fire[i].r][fire[i].c] = true;
q.push({ fire[i] });
}
while (!q.empty()) {
POS cur = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int nr = cur.r + dr[dir];
int nc = cur.c + dc[dir];
if (nr < 0 || nr >= N || nc < 0 || nc >= M || visit[nr][nc]) {
continue;
}
if (map[nr][nc] == 0) {
ret--;
visit[nr][nc] = true;
q.push({ nr,nc });
}
}
}
return ret;
}
void solve(int cnt, int idx) { // 재귀 함수로 완전 탐색
if (idx >= (int)safe_zone.size()) return;
if (cnt == 3) {
int candi = fire_spread();
if (candi > ans) {
ans = candi;
}
return;
}
// 현재 index가 가르키는 safe zone 벽으로 만들기
map[safe_zone[idx].r][safe_zone[idx].c] = 1;
solve(cnt + 1, idx + 1);
map[safe_zone[idx].r][safe_zone[idx].c] = 0;
// 현재 index가 가르키는 safe zone 벽으로 만들지 않기
solve(cnt, idx + 1);
}
int main() {
scanf("%d %d", &N, &M);
for (int r = 0; r < N; r++) {
for (int c = 0; c < M; c++) {
scanf("%d", &map[r][c]);
if (map[r][c] == 0) {
safe_zone.push_back({ r,c });
}
else if (map[r][c] == 2) {
fire.push_back({ r,c });
}
}
}
solve(0, 0);
printf("%d", ans);
return 0;
}
'myt-algorithm-practice > Samsung SW Certi Adv' 카테고리의 다른 글
[Algorithm][C++] SWEA 5656. [모의 SW 역량 테스트] 벽돌 깨기 (0) | 2021.11.01 |
---|---|
[Algorihtm][C++] JUNGOL 4199. swat 로봇청소기 (0) | 2021.11.01 |
[Algorithm][C++] JUNGOL 4197: swat. 연습실 (0) | 2021.10.28 |
[Algorithm][C++] JUNGOL 4193: swat. 애벌레 키우기1 (0) | 2021.10.28 |
[Algorithm][C++] SWEA 1249. [S/W 문제해결 응용] 보급로 문제 (0) | 2021.10.27 |