4408번 자기 방으로 돌아가기
해결방법
BFS 탐색을 통해 이동 경로를 구하는 문제이다
⭐️ 솔루션 ⭐️
먼저,
3 x 200
배열을 선언해 방과 복도를 배정한다출발노드에서 BFS 탐색을 시작한다
- 복도인 경우만 탐색을 진행하며, 도착방에 도착한 경우는 예외로 처리한다
- 현재방과 도착방의 차이를 구해 왼쪽 or 오른쪽 진행을 결정한다
- 도착방을 지나치지 않도록 처리한다
이렇게 탐색을 진행하며, 이동 경로를 dist 배열에 기록한다
모든 학생들이 이동을 마쳤다면, 이 때 중첩된 경로 중 가장 큰 값이 걸린 시간이다
시간 복잡도
각 n개의 경우별로 BFS 탐색을 수행한다
이 때, 복도 + 출발방 + 도착방 을 대상으로만 탐색을 진행하기 때문에 202 만큼의 시간이 걸린다
따라서
O(n * 202)
의 시간 복잡도를 가진다
소스코드
문제 해결 시간 : 1h
메모리 : 12640 KB
시간 : 11 ms
#include <iostream>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int, int> node;
int testcase;
int n,ans;
int from,to;
int sx,sy,ex,ey,turn;
int map[3][200];
int dist[3][200];
bool visited[3][200];
int dx[4] = {0,0,-1,1};
int dy[4] = {1,-1,0,0};
void getPos(){
// 시작 노드 구하기
if(from % 2 == 1) sx = 0;
else sx = 2;
sy = (from + 1) / 2 - 1;
// 도착 노드 구하기
if(to % 2 == 1) ex = 0;
else ex = 2;
ey = (to + 1) / 2 - 1;
// 이동 방향 구하기
if(from < to) turn = 1;
else turn = 0;
}
void bfs(){
queue<node> q;
q.push(node(sx,sy));
visited[sx][sy] = true;
while(!q.empty()){
int x = q.front().first;
int y = q.front().second;
q.pop();
// 방에 도착했으면 탐색 종료
if(map[x][y] == to){
return;
}
for(int i=0; i<4; i++){
// 진행방향이 아닌경우 제외
if(turn==i) continue;
int nx = x + dx[i];
int ny = y + dy[i];
// 맵 밖을 벗어나거나, 복도에서 도착방이 아닌 다른 방을 방문한 경우 제외
if(nx<0 || ny<0 || nx>=200 || ny>=200) continue;
if(nx != 1 && map[nx][ny] != to) continue;
// 도착방을 지나쳐 가는 경우 제외
if(turn==0 && ny<ey) continue;
if(turn==1 && ny>ey) continue;
if(!visited[nx][ny]){
q.push(node(nx,ny));
visited[nx][ny] = true;
dist[nx][ny] += 1;
}
}
}
}
int main(int argc, const char * argv[]) {
// cin,cout 속도향상
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> testcase;
for(int t=1; t<=testcase; t++){
cin >> n;
// 방번호 설정
int nn = 1;
for(int j=0; j<200; j++){
for(int i=0; i<3; i++){
if(i==1){
map[i][j] = 0;
}
else{
map[i][j] = nn;
nn++;
}
dist[i][j] = 0;
}
}
// 입력
for(int i=0; i<n; i++){
cin >> from >> to;
memset(visited, false, sizeof(visited));
getPos();
bfs();
}
ans = 0;
for(int j=0; j<200; j++){
ans = max(ans,dist[1][j]);
}
cout << "#" << t << " " << ans << "\n";
}
return 0;
}
'Algorithm > SWEA 문제풀이' 카테고리의 다른 글
[SWEA] 3752번 가능한 시험 점수 (0) | 2019.03.15 |
---|---|
[SWEA] 2891번 분수 스도쿠 (0) | 2019.03.15 |
[SWEA] 4261번 빠른 휴대전화 키패드 (0) | 2019.03.15 |
[SWEA] 5656번 벽돌 깨기 (1) | 2019.03.15 |
[SWEA] 5644번 무선 충전 (0) | 2019.03.15 |