일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- object detection
- 백트래킹
- BFS
- 문자열
- 다익스트라
- 플로이드 와샬
- 너비 우선 탐색
- 가끔은_말로
- DP
- 알고리즘
- 분할 정복
- 우선 순위 큐
- 크루스칼
- dfs
- Overfitting
- 세그먼트 트리
- lazy propagation
- 2023
- 회고록
- NEXT
- pytorch
- 자바스크립트
- back propagation
- c++
- 미래는_현재와_과거로
- 이분 탐색
- tensorflow
- 가끔은 말로
- dropout
- 조합론
Archives
- Today
- Total
Doby's Lab
백준 16946번: 벽 부수고 이동하기 4 (C++) 본문
https://www.acmicpc.net/problem/16946
16946번: 벽 부수고 이동하기 4
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이
www.acmicpc.net
Solved By: Flood-Fill
저번 포스팅과 이어지는 문제입니다. Flood-Fill이 무엇인지 배웠다면 이것을 사용하여 시간문제를 해결할 수도 있습니다. 1인 칸에서 0의 개수를 세는 BFS는 다른 1인 칸에서도 개수를 셀 수 있기 때문에 꽤 오래 걸립니다.
하지만, 4가지 방향을 확인했을 때, 어떤 0이 어떤 영역에 속하는지 알고, 그 영역의 크기를 안다면 각 1칸당 O(4)로 시간을 단축시킬 수 있습니다.
외람된 말이지만 result 2차원 배열을 선언하여 답을 구하는 방법은 틀리고, 입력받은 배열을 그대로 사용하는 코드가 맞았는데 메모리 문제인지 틀린 답을 도출하는지는 아직 파악이 안 됩니다..
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#define MAX 1001
using namespace std;
int n, m;
int graph[MAX][MAX];
bool visited[MAX][MAX];
// flood fill 관련 선언 data structure
int zeroAreaNum[MAX][MAX]; // 각 Coor가 어느 영역에 속하는지 번호로 나타냄
int zeroAreaCnt = 0; // 그 번호가 이 변수임
vector<int> zeroArea; // 해당 영역의 영역 크기 값
//
struct Point{
int y, x;
};
Point dir[4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// flood-fill
void bfs(int row, int col){
queue<Point> q;
q.push({row, col});
visited[row][col] = true;
zeroAreaNum[row][col] = zeroAreaCnt;
int area = 1;
while(!q.empty()){
int ny = q.front().y;
int nx = q.front().x;
q.pop();
for(int i = 0; i < 4; i++){
int dy = ny + dir[i].y;
int dx = nx + dir[i].x;
if(dy <= n && dy >= 1 && dx <= m && dx >= 1){
if(!visited[dy][dx] && graph[dy][dx] == 0){
area++;
visited[dy][dx] = 1;
q.push({dy, dx});
zeroAreaNum[dy][dx] = zeroAreaCnt;
}
}
}
}
zeroArea.push_back(area);
return;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
for(int i = 1; i <= n; i++){
string s; cin >> s;
for(int j = 0; j < m; j++){
graph[i][j + 1] = s[j] - '0';
}
}
// 각 좌표의 영역 번호 init
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
zeroAreaNum[i][j] = -1;
}
}
// 0끼리 붙어있는 위치들을 flood-fill로 영역화 시킨다.
// 영역들의 번호를 매기고, 그 영역 번호의 해당하는 크기 값을 리턴하도록 한다.
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(!visited[i][j] && graph[i][j] == 0){
bfs(i, j);
zeroAreaCnt++;
}
}
}
// 왜 result라는 새로운 2차원 배열을 선언한 후에
// graph[i][j] == 1이면 result[i][j]에서 4가지 방향 탐색 후, +1하면
// 답이라고 하지 않는걸까
// 메모리 초과라고 하기엔 '틀렸습니다'가 나오기 때문에
// 틀린 답을 도출한다는 소리인데..
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(graph[i][j] == 1){
set<int> st;
for(int k = 0; k < 4; k++){
int dy = i + dir[k].y;
int dx = j + dir[k].x;
if(dy >= 1 && dy <= n && dx >= 1 && dx <= m){
if(zeroAreaNum[dy][dx] == -1) continue;
int getAreaNum = zeroAreaNum[dy][dx];
if(st.count(getAreaNum) == 0){
st.insert(getAreaNum);
graph[i][j] += zeroArea[getAreaNum];
}
}
}
graph[i][j] %= 10;
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cout << graph[i][j];
}
cout << '\n';
}
return 0;
}
728x90
'PS > BOJ' 카테고리의 다른 글
백준 5847번: Milk Scheduling (C++) (0) | 2022.05.30 |
---|---|
백준 1948번: 임계경로 (C++) (0) | 2022.05.30 |
백준 1926번: 그림 (C++) (0) | 2022.05.29 |
백준 2358번: 평행선 (C++) (0) | 2022.05.28 |
백준 7575번: 바이러스 (C++) (0) | 2022.05.28 |