백준 그래프 1697번 숨박꼭질

2020. 3. 17. 00:16Algorithm/문제풀이

https://www.acmicpc.net/problem/1697

 

1697번: 숨바꼭질

문제 수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때 걷는다면 1초 후에 X-1 또는 X+1로 이동하게 된다. 순간이동을 하는 경우에는 1초 후에 2*X의 위치로 이동하게 된다. 수빈이와 동생의 위치가 주어졌을 때, 수빈이가 동생을 찾을 수 있는 가장 빠른 시간이 몇 초 후인지

www.acmicpc.net

수빈이가 동생에게 도달하는 최소의 시간을 구하는 문제입니다. 해당 좌표까지 가는데 3가지 방법이 있는데 이는 x2, +1, -1이 있습니다. 

그래서 최소의 시간으로 도달할 수 있는  방법을 구하는 겁니다. 그래서 그래프 중에서도 최소의 시간으로 도달하기 위해 bfs를 사용하면 됩니다. 그래서 그래프 모양을 그려보면 아래와 같습니다. 

 

그래프

그리고 한번 방문했던 좌표는 다시 방문하지 않게 check해주어야 합니다. 

 

더보기
#include <cstdio>
#include <queue>
#include <utility>

using namespace std;

int map[300000];
queue <pair<int, int> > qu;

int N, K;

void bfs();
int isValidPoint(int point);
int isDestinationPoint(int point);

int main(){
	scanf("%d %d", &N, &K);
	bfs();
}

void bfs(){
	qu.push(make_pair(0, N));
	map[N] = 1;

	while(!qu.empty()){
		pair<int, int> previousPoint = qu.front();
		qu.pop();
		
		if(isDestinationPoint(previousPoint.second)){
			printf("%d", previousPoint.first);
			break;
		}

		int movePoint[3];
		movePoint[0] = previousPoint.second * 2;
		movePoint[1] = previousPoint.second + 1;
		movePoint[2] = previousPoint.second - 1;
		
		if(isValidPoint(movePoint[0])){
			qu.push(make_pair(previousPoint.first+1, movePoint[0]));
			map[movePoint[0]] = 1;
		}
		if(isValidPoint(movePoint[1])){
			qu.push(make_pair(previousPoint.first+1, movePoint[1]));
			map[movePoint[1]] = 1;
		}
		if(isValidPoint(movePoint[2]) && movePoint[2] >= 0){
			qu.push(make_pair(previousPoint.first+1, movePoint[2]));
			map[movePoint[2]] = 1;
		}
	}
}


int isValidPoint(int point){
	if(point <= 100000 && !map[point])
		return 1;
	else return 0;
}

int isDestinationPoint(int point){
	if(K==point)
		return 1;
	else return 0;
}

'Algorithm > 문제풀이' 카테고리의 다른 글

백준 1520 내리막길  (0) 2020.03.27
백준 그래프 2206 벽 부수고 이동하기  (0) 2020.03.17
1629번 곱셈  (0) 2020.02.20
백준 2004 조합 0의 개수  (0) 2020.02.20
dp 백준 9251 LCS  (0) 2020.02.02