반응형
https://www.acmicpc.net/problem/16946
16946번: 벽 부수고 이동하기 4
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이
www.acmicpc.net
[ 문제풀이 ]
매 벽마다 움직일 수 있는 공간을 체크하게 되면은 최악의 경우 O(N*M*N*M)이 되어서 시간 초과가 날 확률이 높기 때문에 배열을 한 번만 돌면서 문제를 해결할 방법을 찾아야 했습니다.
일단 값을 입력받고, 전체 배열을 돌면서 값이 '1'인 좌표에는 최종 정답 배열에 1을 더해주었고, '0'인 좌표마다 모두 들러서 빈 공간의 개수를 체크했습니다.
그리고 빈 공간에 방문할 때마다 방문을 체크해주기 위해 배열 값을 'a'로 경신해 주었습니다.
또한 벽을 만나게 되면 벽의 좌표를 vect배열에 넣어주고 bfs함수의 마지막에 각 좌표에 카운트한 값을 더해주었습니다.
위 과정을 거치면 아래와 같은 결과를 얻을 수 있습니다.
모든 좌표에 대해 위의 과정을 거치면 다음과 같은 결과를 얻을 수 있습니다.
[ 소스 코드 ]
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include <iostream> #include <queue> #include <vector> #include <cstring> using namespace std; int N, M; char arr[1001][1001]; //값을 입력 받을 배열 int ans[1001][1001]; //정답을 기록할 배열 int visited[1001][1001]; //방문을 체크할 배열 int dy[4] = { -1,1,0,0 }; //방향 배열 int dx[4] = { 0,0,-1,1 }; struct pos { int y; int x; }; void bfs(int y, int x) { queue<pos> q; vector<pos> vect; q.push({ y,x }); arr[y][x] = 'a'; int cnt = 1; while (!q.empty()) { int curY = q.front().y; int curX = q.front().x; q.pop(); for (int i = 0; i < 4; i++) { int yy = curY + dy[i]; int xx = curX + dx[i]; if (yy >= 0 && yy < N && xx >= 0 && xx < M) { if (arr[yy][xx] == '0') { arr[yy][xx] = 'a'; //배열값을 'a'로 초기화하면서 다시 방문하지 못하게 한다. cnt++; //갈 수 있는 곳의 수를 저장 q.push({ yy,xx }); } if (arr[yy][xx] == '1' && visited[yy][xx] != 1) { //벽을 만나면 visited에 기록하고 좌표를 저장 visited[yy][xx] = 1; vect.push_back({ yy,xx }); } } } } for (int i = 0; i < vect.size(); i++) { int yy = vect[i].y; int xx = vect[i].x; visited[yy][xx] = 0; //방문 기록을 없애고 ans[yy][xx] += cnt; //해당 좌표에 cnt값을 더해줌 } } int main() { cin >> N >> M; for (int i = 0; i < N; i++) { cin >> arr[i]; } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (arr[i][j] == '0') { bfs(i, j); //해당 배열의 값이 '0'이라면 } //bfs를 돌린다 else if (arr[i][j] == '1') { ans[i][j]++; //해당 값이 '1'이라면 총 카운트 수에서 1을 더해준다 } } } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cout << ans[i][j] % 10; //10으로 나눈 나머지 값을 출력한다. } cout << endl; } } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 1509번 - 팰린드롬 분할 (C++) (0) | 2022.05.26 |
---|---|
[ 백준 ] 1208번 - 부분수열의 합 2 (C++) (0) | 2022.05.25 |
[ 백준 ] 17387번 - 선분 교차 2 (C++) (0) | 2022.05.24 |
[ 백준 ] 17143번 - 낚시왕 (C++) (0) | 2022.05.23 |
[ 백준 ] 12100번 - 2048(Easy) (C++) (0) | 2022.05.21 |