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
- CSS
- react-router-dom
- 리액트최적화
- GridItem
- react fsd
- 리렌더링최적화
- featured-sliced-design
- BFS
- LazyVGrid
- SwiftUI Font
- navigationBar 숨기기
- 블로그업로드확인
- 상단 빈공간 제거
- 반응형 css
- react상태관리라이브러리
- 동기 함수 내에서 비동기 함수 호출
- 가로모드끄기
- @published 프로퍼티 래퍼
- zustand란
- LazyHGrid
- @observedobject 프로퍼티 래퍼
- 페이지전환
- zustand
- 비동기함수
- react hook
- 컴퓨터네트워크
- @environmentobject 프로퍼티 래퍼
- 페이지이동함수
- C++
- 세로모드끄기
Archives
- Today
- Total
leebaek
[BOJ/16933번벽부수고이동하기3] c++ / 본문
문제
(1, 1)칸에서 (N, M)칸까지 가는 최단 경로를 구하는 문제
-벽 K개를 부술 수 있음
-낮과 밤이 존재함
-낮에만 벽 부수고 이동가능
-이동하거나 제자리에 머무를 수 있음 ( 이동하지 않아도 하루가 지났다고 봄 )
-한가지 동작(이동, 제자리) 수행하면 낮밤이 바뀜
생각
벽부수고 이동하기 2에서 낮과 밤이라는 조건이 더 붙음
낮밤 변수 써서 풀면 되겠다 생각함
처음에 vis에 낮밤 차원을 하나 더 만들어서 풀었는데 뭔가 안됨
큐에서 팝 될 때 낮밤이 다 다를건데 그걸 고려하지 못함
해결법은 큐를 푸쉬할 때 낮밤 정보를 주는것 !!
문제풀이
1. 일단 bfs 문제랑 똑같음
2. 낮이라면,
-1) 벽이 아님 & 방문표시 없음 : 방문표시 & 큐에 푸쉬 ( nx, ny, B, cnt+1, 밤 )
-2) 벽 & 방문표시 없음 & B < K ( 벽을 부술 수 있음 ) : 방문표시 & 큐에 푸쉬 ( nx, ny, B+1, cnt+1, 밤 )
3. 밤이라면,
-1) 벽이 아님 & 방문표시 없음 : 방문표시 & 큐에 푸쉬 ( nx, ny, B, cnt+1, 낮 )
-2) 벽 & 방문표시 없음 & B < K ( 벽을 부술 수 있음 ) : 큐에 푸쉬 ( x, y, B, cnt+1, 낮 ) -> 이동하지 않고 제자리에 있음
4.반복문 돌다가 (N-1, M-1)칸까지 오면 cnt 반환하고 종료
5.반복문에서 벗어난다면 -1 반환
코드
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
#define X first
#define Y second
int board[1001][1001];
int vis[1001][1001][11];
int N, M, K;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {1, 0, -1, 0};
int BFS() {
queue<pair<tuple<int, int, int>, pair<int, int>>> Q; // 순서대로 x, y, B, cnt, m/n
Q.push({{0, 0, 0}, {1, 0}});
vis[0][0][0] = 1;
while (!Q.empty()) {
int x = get<0>(Q.front().X);
int y = get<1>(Q.front().X);
int B = get<2>(Q.front().X);
int cnt = Q.front().Y.X;
int day = Q.front().Y.Y;
Q.pop();
if ( x == N-1 && y == M-1 )
return cnt;
for ( int dir = 0; dir < 4; dir++ ) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if ( nx < 0 || nx >= N || ny < 0 || ny >= M ) continue;
if ( day == 0 ) { // 낮인 경우
if ( board[nx][ny] == 0 && vis[nx][ny][B] == 0 ) { // 벽이 아닌 경우
vis[nx][ny][B] = 1;
Q.push({{nx, ny, B}, {cnt+1, 1}});
}
else if ( board[nx][ny] == 1 && B < K && vis[nx][ny][B+1] == 0 ) { // 벽인 경우
vis[nx][ny][B+1] = 1;
Q.push({{nx, ny, B+1}, {cnt+1, 1}});
}
}
else { // 밤인 경우
if ( board[nx][ny] == 0 && vis[nx][ny][B] == 0 ) { // 벽이 아닌 경우
vis[nx][ny][B] = 1;
Q.push({{nx, ny, B}, {cnt+1, 0}});
}
else if ( board[nx][ny] == 1 && B < K && vis[nx][ny][B+1] == 0 ) { // 벽인 경우
Q.push({{x, y, B}, {cnt+1, 0}});
}
}
}
}
return -1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> K;
for ( int i = 0; i < N; i++ ) {
string str;
cin >> str;
for ( int j = 0; j < M; j++ ) {
int tmp = str[j]-'0';
board[i][j] = tmp;
}
}
cout << BFS();
}
'BOJ_C++_PS' 카테고리의 다른 글
[BOJ/2468번안전영역] c++ / BFS (0) | 2023.09.27 |
---|---|
[BOJ/16946번벽부수고이동하기4] c++ / BFS (2) | 2023.09.26 |
[BOJ/14442번벽부수고이동하기2] c++ / BFS (0) | 2023.09.24 |
[BOJ/2206번벽부수고이동하기] c++ / BFS (0) | 2023.09.23 |
[BOJ/7569토마토2] c++ / BFS (0) | 2023.09.22 |