일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- lazy propagation
- 분할 정복
- 세그먼트 트리
- 가끔은_말로
- 2023
- 너비 우선 탐색
- 자바스크립트
- BFS
- 알고리즘
- 조합론
- 우선 순위 큐
- 이분 탐색
- 백트래킹
- 가끔은 말로
- 다익스트라
- 플로이드 와샬
- c++
- Overfitting
- tensorflow
- 크루스칼
- 회고록
- dfs
- 문자열
- 미래는_현재와_과거로
- object detection
- back propagation
- DP
- pytorch
- NEXT
- dropout
Archives
- Today
- Total
Doby's Lab
[알고리즘] 백준 2468번: 안전 영역 (C++), 최소 조건을 확인하라 본문
이번 문제에서 크게 어려웠던 점은 없었으나 각 문제에 대한 포인트를 항상 블로그에 담아두려 하기 때문에 가져왔다.
문제에서 헷갈릴 수 있는 건 visited의 리셋이었다.
비의 높이에 따라 bfs를 해주며 건물의 개수를 cnt하며 배열에 따로 담았었다. 하지만, cnt를 담은 배열을 디버깅해보니 처음을 제외하고는 전부 0이었다. 이 부분에서 visited를 초기화시키지 않았구나라는 것을 알고 reset 함수를 작성하고, 비에 높이에 따라 건물 cnt가 끝날 때마다 reset 함수를 콜 해주었다.
[코드]
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int map[101][101] = { 0, };
bool visited[101][101] = { 0, };
int n;
typedef struct {
int y, x;
} Direction;
Direction dir[4] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void bfs(int row, int col, int rain) {
queue<pair<int, int>> q;
q.push(make_pair(row, col));
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int dy = y + dir[i].y;
int dx = x + dir[i].x;
if (!visited[dy][dx] && map[dy][dx] > rain) {
visited[dy][dx] = 1;
q.push(make_pair(dy, dx));
}
}
}
}
void reset() {// visited 전면 초기화
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
visited[i][j] = 0;
}
}
}
int main() {
cin >> n;
int max = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int idx;
cin >> idx;
map[i][j] = idx;
if (idx > max) {
max = idx;
}
}
}
vector<int> cntArr;
for (int rain = 1; rain <= max; rain++) {
int cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (!visited[i][j] && map[i][j] > rain) {
visited[i][j] = 1;
bfs(i, j, rain);
cnt++;
}
}
}
reset();
cntArr.push_back(cnt);
}
sort(cntArr.begin(), cntArr.end());
cout << cntArr.back();
return 0;
}
하지만, 이는 76%까지 밖에 가지 못 한다.
이 정도의 퍼센티지라면 논리는 맞으나 어딘가에 반례가 있다고 생각했다.
이 문제의 포인트 (이번 포스팅의 이유)
가끔 문제를 풀 때 논리는 맞는 거 같지만 반례가 존재하는 듯 해보일 때는 항상 문제에서 가질 수 있는 최솟값을 먼저 넣어보라는 댓글을 봤었다.
이를 기억하고
1
1
값을 넣어준 결과 내가 도출해내려는 값 0이 나오는 것은 틀리지 않았었다.
'장마철이라고 해서 당연히 비가 한 방울이라도 오겠지'라는 생각이었다.
하지만, 문제에서 말하는 힌트가 있었다.
'장마철인데 왜..?'라는 생각이 들었지만 이에 따라 코드를 고쳐주었다.
(지금 생각해보니 장마철이라고 다 물에 잠기지는 않네)
그저 for문에서 rain의 시작 값을 1에서 0으로 고쳐주기만 하면 된다.
[정답 코드]
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int map[101][101] = { 0, };
bool visited[101][101] = { 0, };
int n;
typedef struct {
int y, x;
} Direction;
Direction dir[4] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
void bfs(int row, int col, int rain) {
queue<pair<int, int>> q;
q.push(make_pair(row, col));
while (!q.empty()) {
int y = q.front().first;
int x = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int dy = y + dir[i].y;
int dx = x + dir[i].x;
if (!visited[dy][dx] && map[dy][dx] > rain) {
visited[dy][dx] = 1;
q.push(make_pair(dy, dx));
}
}
}
}
void reset() {// visited 전면 초기화
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
visited[i][j] = 0;
}
}
}
int main() {
cin >> n;
int max = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int idx;
cin >> idx;
map[i][j] = idx;
if (idx > max) {
max = idx;
}
}
}
vector<int> cntArr;
for (int rain = 0; rain <= max; rain++) {
int cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (!visited[i][j] && map[i][j] > rain) {
visited[i][j] = 1;
bfs(i, j, rain);
cnt++;
}
}
}
reset();
cntArr.push_back(cnt);
}
sort(cntArr.begin(), cntArr.end());
cout << cntArr.back();
return 0;
}
728x90
'PS > BOJ' 카테고리의 다른 글
[자료구조] 백준 7662번: 이중 우선순위 큐 (C++), 두 큐를 하나처럼, 싱크의 핵심 (0) | 2021.10.21 |
---|---|
[알고리즘] 백준 1245번: 농장 관리 (C++), DFS의 논리 접근법 -> 필터링 (0) | 2021.10.20 |
[알고리즘] 백준 1629번: 곱셈 (C++), 분할 정복 개념, 분할 정복을 이용한 거듭제곱 (0) | 2021.10.17 |
[알고리즘] 백준 1987번: 알파벳 (C++), 오류와 오류와 오류 (0) | 2021.10.15 |
[알고리즘] 백준 3079번: 입국심사 (C++), 이분탐색이라는 전제가 없었다면 풀 수 있었을까 (0) | 2021.10.13 |