1일1알

백준 12851번 숨바꼭질2 C++ 본문

알고리즘

백준 12851번 숨바꼭질2 C++

영춘권의달인 2021. 10. 20. 12:46

출처: https://www.acmicpc.net/problem/12851

bfs로 풀 수 있는 문제인데 특이한 점은 가장 빠른 시간만 구하는 게 아니라 그 방법이 몇 가지인지까지 구해야 한다.

최초 도달했을 때 시간을 구하고 그 시간과 같은 시간에 도착 할때마다 Count를 증가시켜주면 된다.

 

#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <unordered_set>

using namespace std;
typedef long long ll;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n, k;
	cin >> n >> k;
	vector<bool> visited(100001, false);
	queue<pair<int, int>> q;
	q.push({ n,0 });
	visited[n] = true;
	int min = 987654321;
	int cnt = 0;
	while (!q.empty()) {
		auto a = q.front();
		if (a.second > min) {
			q.pop();
			continue;
		}
		visited[a.first] = true;
		q.pop();
		if (cnt == 0 && a.first == k) {
			min = a.second;
			cnt++;
		}
		else if (cnt != 0 && a.first == k && min == a.second) {
			cnt++;
		}
		if (a.first + 1 <= 100000) {
			if (!visited[a.first + 1]) {
				q.push({ a.first + 1,a.second + 1 });
			}
		}
		if (a.first - 1 >= 0) {
			if (!visited[a.first - 1]) {
				q.push({ a.first - 1, a.second + 1 });
			}
		}
		if (a.first * 2 <= 100000) {
			if (!visited[a.first * 2]) {
				q.push({ a.first * 2,a.second + 1 });
			}
		}
	}
	cout << min << "\n" << cnt;
};