[C++] 깊이 μš°μ„  탐색(DFS), λ„ˆλΉ„ μš°μ„  탐색(BFS)

2020. 5. 1. 10:50Β·πŸ“ Computer Science/✏ Algorithm

깊이 μš°μ„  탐색(Depth First Search)κ³Ό λ„ˆλΉ„ μš°μ„  탐색(Breadth First Search)

깊이 μš°μ„  탐색은 ν•œ λ°©ν–₯으둜 계속 κ°€λ‹€κ°€ 더 이상 갈 수 μ—†μœΌλ©΄ λΆ€λͺ¨ λ…Έλ“œλ‘œ λŒμ•„μ™€ λ‹€λ₯Έ λ°©ν–₯으둜 νƒμƒ‰ν•œλ‹€.

  • 주둜 Stackμ΄λ‚˜ μž¬κ·€ ν•¨μˆ˜λ₯Ό μ΄μš©ν•΄ κ΅¬ν˜„ν•œλ‹€.
  • λͺ¨λ“  λ…Έλ“œλ₯Ό λ°©λ¬Έν•˜κ±°λ‚˜ κ°€μ€‘μΉ˜, 이동 과정에 μ œμ•½μ΄ μžˆμ„ κ²½μš°μ— μ‚¬μš©ν•˜λ©΄ μ’‹λ‹€.
  • 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” μˆœν™˜ μ•Œκ³ λ¦¬μ¦˜μ˜ ν˜•νƒœλ₯Ό κ°–κ³  μžˆλ‹€.
  • BFS보닀 μ’€ 더 κ°„λ‹¨ν•˜λ‚˜ λ‹¨μˆœ 검색 속도 μžμ²΄λŠ” BFS보닀 λŠλ¦¬λ‹€.

DFS

 

λ„ˆλΉ„ μš°μ„  탐색은 ν˜„μž¬ λ…Έλ“œμ—μ„œ κ°€μž₯ κ°€κΉŒμš΄ λ…Έλ“œλ₯Ό λ¨Όμ € λ°©λ¬Έν•΄ νƒμƒ‰ν•œλ‹€.

  • 주둜 Queueλ₯Ό μ΄μš©ν•΄ κ΅¬ν˜„ν•œλ‹€.
  • 두 λ…Έλ“œ μ‚¬μ΄μ˜ μ΅œλ‹¨ 경둜 ν˜Ήμ€ μž„μ˜μ˜ 경둜λ₯Ό μ°ΎλŠ” κ²½μš°μ— μ‚¬μš©ν•˜λ©΄ μ’‹λ‹€.

 

BFS

 

κΈ°λ³Έ 원리

 

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

 

1260번: DFS와 BFS

첫째 쀄에 μ •μ μ˜ 개수 N(1 ≤ N ≤ 1,000), κ°„μ„ μ˜ 개수 M(1 ≤ M ≤ 10,000), 탐색을 μ‹œμž‘ν•  μ •μ μ˜ 번호 Vκ°€ μ£Όμ–΄μ§„λ‹€. λ‹€μŒ M개의 μ€„μ—λŠ” 간선이 μ—°κ²°ν•˜λŠ” 두 μ •μ μ˜ λ²ˆν˜Έκ°€ μ£Όμ–΄μ§„λ‹€. μ–΄λ–€ 두 정점 사이에 μ—¬λŸ¬ 개의 간선이 μžˆμ„ 수 μžˆλ‹€. μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” 간선은 μ–‘λ°©ν–₯이닀.

www.acmicpc.net

#include <iostream> 
#include <algorithm> 
#include <vector>
#include <queue>
using namespace std;

vector<int> graph[1001]; // μ—°κ²° κ·Έλž˜ν”„
bool checked[1001]; // 방문 체크

void DFS(int start)
{
	checked[start] = true;
	cout << start << " ";
	for (int i = 0; i < graph[start].size(); i++)
		if (!checked[graph[start][i]])
			DFS(graph[start][i]);
}

void BFS(int start)
{
	queue<int> q;
	q.push(start);
	checked[start] = true;
	while (!q.empty()) {
		int val = q.front();
		cout << val << " ";
		q.pop();
		for (int i = 0; i < graph[val].size(); i++)
			if (!checked[graph[val][i]]) {
				q.push(graph[val][i]);
				checked[graph[val][i]] = true;
			}
	}
}

int main()
{
	int N, M, V;
	cin >> N >> M >> V;
	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	for (int i = 1; i <= N; i++)
		sort(graph[i].begin(), graph[i].end());

	fill_n(checked, N + 1, false);
	DFS(V);
	cout << "\n";
	fill_n(checked, N + 1, false);
	BFS(V);
}

 

문제 : DFS

 

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

 

2667번: λ‹¨μ§€λ²ˆν˜ΈλΆ™μ΄κΈ°

<κ·Έλ¦Ό 1>κ³Ό 같이 μ •μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ 지도가 μžˆλ‹€. 1은 집이 μžˆλŠ” 곳을, 0은 집이 μ—†λŠ” 곳을 λ‚˜νƒ€λ‚Έλ‹€. μ² μˆ˜λŠ” 이 지도λ₯Ό κ°€μ§€κ³  μ—°κ²°λœ μ§‘λ“€μ˜ λͺ¨μž„인 단지λ₯Ό μ •μ˜ν•˜κ³ , 단지에 번호λ₯Ό 뢙이렀 ν•œλ‹€. μ—¬κΈ°μ„œ μ—°κ²°λ˜μ—ˆλ‹€λŠ” 것은 μ–΄λ–€ 집이 쒌우, ν˜Ήμ€ μ•„λž˜μœ„λ‘œ λ‹€λ₯Έ 집이 μžˆλŠ” 경우λ₯Ό λ§ν•œλ‹€. λŒ€κ°μ„ μƒμ— 집이 μžˆλŠ” κ²½μš°λŠ” μ—°κ²°λœ 것이 μ•„λ‹ˆλ‹€. <κ·Έλ¦Ό 2>λŠ” <κ·Έλ¦Ό 1>을 λ‹¨μ§€λ³„λ‘œ 번호λ₯Ό 뢙인 것이닀. 지도λ₯Ό μž…λ ₯ν•˜μ—¬ λ‹¨μ§€μˆ˜λ₯Ό 좜λ ₯ν•˜κ³ , 각 단지에 μ†ν•˜λŠ” μ§‘μ˜ 수

www.acmicpc.net

#include <iostream> 
#include <set> 
using namespace std;

int n;
bool map[25][25], checked[25][25];

int DFS(int y, int x)
{
	if (0 > y || y >= n || 0 > x || x >= n)
		return 0;
	if (checked[y][x] || !map[y][x])
		return 0;
	checked[y][x] = true;
	return 1 + DFS(y, x + 1) + DFS(y, x - 1) + DFS(y + 1, x) + DFS(y - 1, x);
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			scanf("%1d", &map[i][j]);

	multiset<int> s;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (map[i][j] && !checked[i][j])
				s.insert(DFS(i, j));

	cout << s.size() << "\n";
	for (int i : s)
		cout << i << "\n";
}

 

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

 

2606번: λ°”μ΄λŸ¬μŠ€

첫째 μ€„μ—λŠ” μ»΄ν“¨ν„°μ˜ μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. μ»΄ν“¨ν„°μ˜ μˆ˜λŠ” 100 μ΄ν•˜μ΄κ³  각 μ»΄ν“¨ν„°μ—λŠ” 1번 λΆ€ν„° μ°¨λ‘€λŒ€λ‘œ λ²ˆν˜Έκ°€ 맀겨진닀. λ‘˜μ§Έ μ€„μ—λŠ” λ„€νŠΈμ›Œν¬ μƒμ—μ„œ 직접 μ—°κ²°λ˜μ–΄ μžˆλŠ” 컴퓨터 쌍의 μˆ˜κ°€ μ£Όμ–΄οΏ½οΏ½

www.acmicpc.net

#include <iostream> 
#include <vector>
using namespace std;

int ans = -1;
vector<int> graph[101];
bool checked[101];

void DFS(int start) {
	ans++;
	checked[start] = true;
	for (int i = 0; i < graph[start].size(); i++)
		if (!checked[graph[start][i]])
			DFS(graph[start][i]);
}

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0, a, b; i < m; i++) {
		cin >> a >> b;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	DFS(1);
	cout << ans;
}

 

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

 

2636번: 치즈

μ•„λž˜ <κ·Έλ¦Ό 1>κ³Ό 같이 μ •μ‚¬κ°ν˜• μΉΈλ“€λ‘œ 이루어진 μ‚¬κ°ν˜• λͺ¨μ–‘μ˜ 판이 있고, κ·Έ μœ„μ— 얇은 치즈(νšŒμƒ‰μœΌλ‘œ ν‘œμ‹œλœ λΆ€λΆ„)κ°€ 놓여 μžˆλ‹€. 판의 κ°€μž₯자리(<κ·Έλ¦Ό 1>μ—μ„œ λ„€λͺ¨ 칸에 X친 λΆ€λΆ„)μ—λŠ” μΉ˜μ¦ˆκ°€ 놓

www.acmicpc.net

#include <iostream>
using namespace std;

int N, M;
int time, piece, cnt;
bool map[100][100], check[100][100];
int dir[4][2]{ {1,0},{-1,0},{0,1},{0,-1} };

void DFS(int x, int y)
{
	check[y][x] = true;

	for (int i = 0; i < 4; i++) {
		int nx = x + dir[i][0], ny = y + dir[i][1];

		if (nx < 0 || nx >= M || ny < 0 || ny >= N)
			continue;
		if (check[ny][nx])
			continue;

		if (map[ny][nx]) {
			cnt--;
			map[ny][nx] = false;
			check[ny][nx] = true;
		}
		else
			DFS(nx, ny);
	}
}

int main()
{
	cin >> N >> M;
	for (int i = 0; i < N; i++)
		for (int j = 0; j < M; j++) {
			cin >> map[i][j];
			if (map[i][j])
				cnt++;
		}

	while (cnt) {
		time++;
		piece = cnt;

		DFS(0, 0);

		for (int i = 0; i < N; i++)
			for (int j = 0; j < M; j++)
				check[i][j] = false;
	}

	cout << time << "\n" << piece;
}

 

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

 

14888번: μ—°μ‚°μž λΌμ›Œλ„£κΈ°

첫째 쀄에 수의 개수 N(2 ≤ N ≤ 11)κ°€ μ£Όμ–΄μ§„λ‹€. λ‘˜μ§Έ μ€„μ—λŠ” A1, A2, ..., AN이 μ£Όμ–΄μ§„λ‹€. (1 ≤ Ai ≤ 100) μ…‹μ§Έ μ€„μ—λŠ” 합이 N-1인 4개의 μ •μˆ˜κ°€ μ£Όμ–΄μ§€λŠ”λ°, μ°¨λ‘€λŒ€λ‘œ λ§μ…ˆ(+)의 개수, λΊ„μ…ˆ(-)의 개수, οΏ½οΏ½

www.acmicpc.net

#include <iostream>
using namespace std;

int n; int num[11]; int oper[4];
int mmin = 1000000000, mmax = -1000000000;

void DFS(int idx, int result, int hap, int cha, int gop, int na)
{
	if (hap < 0 || cha < 0 || gop < 0 || na < 0) return;

	if (idx == n) {
		if (result > mmax) mmax = result;
		if (result < mmin) mmin = result;
		return;
	}

	DFS(idx + 1, result + num[idx], hap - 1, cha, gop, na); // +μ—°μ‚°
	DFS(idx + 1, result - num[idx], hap, cha - 1, gop, na); // -μ—°μ‚°
	DFS(idx + 1, result * num[idx], hap, cha, gop - 1, na); // *μ—°μ‚°
	DFS(idx + 1, result / num[idx], hap, cha, gop, na - 1); // /μ—°μ‚°
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> num[i];
	for (int i = 0; i < 4; ++i)
		cin >> oper[i];

	DFS(1, num[0], oper[0], oper[1], oper[2], oper[3]);
	cout << mmax << "\n" << mmin;
}

 

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

 

9466번: ν…€ ν”„λ‘œμ νŠΈ

문제 이번 가을학기에 '문제 ν•΄κ²°' κ°•μ˜λ₯Ό μ‹ μ²­ν•œ 학생듀은 ν…€ ν”„λ‘œμ νŠΈλ₯Ό μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€. ν”„λ‘œμ νŠΈ νŒ€μ› μˆ˜μ—λŠ” μ œν•œμ΄ μ—†λ‹€. 심지어 λͺ¨λ“  학생듀이 λ™μΌν•œ νŒ€μ˜ νŒ€μ›μΈ κ²½μš°μ™€ κ°™μ΄ ν•œ νŒ€λ§Œ

www.acmicpc.net

#include <iostream>
#include <vector>
using namespace std;

int team;
vector<int> v;
vector<bool> check, visited; // 방문, 재방문

void DFS(int start, int index)
{
	if (visited[index]) {
		team++;

		int temp = v[index];
		while (temp != index) {
			team++;
			temp = v[temp];
		}
	}
	else {
		visited[index] = true;
		if (!check[v[index]]) {
			DFS(start, v[index]);
			check[index] = true;
		}
	}
}

int main()
{
	int T;
	cin >> T;
	while (T--) {
		int N;
		cin >> N;

		team = 0;
		v = vector<int>(N + 1, 0);
		check = vector<bool>(N + 1, false);
		visited = vector<bool>(N + 1, false);

		for (int i = 1; i <= N; i++)
			cin >> v[i];

		for (int i = 1; i <= N; i++) {
			if (!check[i]) {
				visited = vector<bool>(N + 1, false);
				DFS(i, i);
			}
		}

		cout << N - team << "\n";
	}
}

 

문제 : BFS

 

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

 

2178번: 미둜 탐색

첫째 쀄에 두 μ •μˆ˜ N, M(2 ≤ N, M ≤ 100)이 μ£Όμ–΄μ§„λ‹€. λ‹€μŒ N개의 μ€„μ—λŠ” M개의 μ •μˆ˜λ‘œ λ―Έλ‘œκ°€ μ£Όμ–΄μ§„λ‹€. 각각의 μˆ˜λ“€μ€ λΆ™μ–΄μ„œ μž…λ ₯으둜 μ£Όμ–΄μ§„λ‹€.

www.acmicpc.net

#include <iostream> 
#include <queue>
using namespace std;

bool map[100][100], ck[100][100];
int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			scanf("%1d", &map[i][j]);

	int ans = 0;
	queue<pair<int, int>> q;
	q.push(make_pair(0, 0));
	ck[0][0] = true;
	while (!q.empty()) {
		ans++;

		int s = q.size();
		while (s--) {
			int tx = q.front().second, ty = q.front().first;
			q.pop();

			if (tx == m - 1 && ty == n - 1) {
				cout << ans;
				return 0;
			}

			for (int i = 0; i < 4; i++) {
				int nx = tx + dir[i][0], ny = ty + dir[i][1];
				if (nx < 0 || nx >= m || ny < 0 || ny >= n)
					continue;

				if (map[ny][nx] && !ck[ny][nx]) {
					q.push({ ny, nx });
					ck[ny][nx] = true;
				}
			}
		}
	}
}

 

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

 

2206번: λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ°

N×M의 ν–‰λ ¬λ‘œ ν‘œν˜„λ˜λŠ” 맡이 μžˆλ‹€. λ§΅μ—μ„œ 0은 이동할 수 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚΄κ³ , 1은 이동할 수 μ—†λŠ” 벽이 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚Έλ‹€. 당신은 (1, 1)μ—μ„œ (N, M)의 μœ„μΉ˜κΉŒμ§€ μ΄λ™ν•˜λ € ν•˜λŠ”λ°, μ΄λ•Œ μ΅œλ‹¨ 경둜둜 μ΄λ™ν•˜λ € ν•œλ‹€. μ΅œλ‹¨κ²½λ‘œλŠ” λ§΅μ—μ„œ κ°€μž₯ 적은 개수의 칸을 μ§€λ‚˜λŠ” 경둜λ₯Ό λ§ν•˜λŠ”λ°, μ΄λ•Œ μ‹œμž‘ν•˜λŠ” μΉΈκ³Ό λλ‚˜λŠ” 칸도 ν¬ν•¨ν•΄μ„œ μ„Όλ‹€. λ§Œμ•½μ— μ΄λ™ν•˜λŠ” 도쀑에 ν•œ 개의 벽을 λΆ€μˆ˜κ³  μ΄λ™ν•˜λŠ” 것이 μ’€ 더 κ²½λ‘œκ°€ μ§§μ•„μ§„λ‹€λ©΄, 벽을 ν•œ 개 κΉŒμ§€ λΆ€μˆ˜κ³  이동

www.acmicpc.net

#include <iostream> 
#include <queue>
using namespace std;

bool map[1000][1000], checked[1000][1000][2];

int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++)
			scanf("%1d", &map[i][j]);

	int answer = 0;
	queue<pair<int, pair<int, int>>> q;
	q.push({ 0, { 0, 0 } });
	checked[0][0][0] = true;
	while (!q.empty()) {
		answer++;

		int size = q.size();
		while (size--) {
			int tx = q.front().second.second;
			int ty = q.front().second.first;
			int crash = q.front().first;
			q.pop();

			if (tx == m - 1 && ty == n - 1) {
				cout << answer;
				return 0;
			}

			int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
			for (int i = 0; i < 4; i++) {
				int nx = tx + dir[i][0], ny = ty + dir[i][1];

				if (nx < 0 || nx >= m || ny < 0 || ny >= n)
					continue;
				if (checked[ny][nx][crash])
					continue;
				if (map[ny][nx]) {
					if (crash)
						continue;
					q.push({ 1,{ny, nx} });
				}
				else
					q.push({ crash,{ny, nx} });

				checked[ny][nx][crash] = true;
			}
		}
	}

	cout << -1;
}

 

 

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

 

7569번: ν† λ§ˆν† 

첫 μ€„μ—λŠ” μƒμžμ˜ 크기λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 두 μ •μˆ˜ M,Nκ³Ό μŒ“μ•„μ˜¬λ €μ§€λŠ” μƒμžμ˜ 수λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Hκ°€ μ£Όμ–΄μ§„λ‹€. M은 μƒμžμ˜ κ°€λ‘œ 칸의 수, N은 μƒμžμ˜ μ„Έλ‘œ 칸의 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

#include <iostream>
#include <queue>
using namespace std;

int map[100][100][100]{};
bool check[100][100][100]{};

int main()
{
	int M, N, H;
	cin >> M >> N >> H;

	queue<pair<int, pair<int, int>>> q;
	for (int i = 0; i < H; ++i)
		for (int j = 0; j < N; ++j)
			for (int k = 0; k < M; ++k) {
				cin >> map[i][j][k];

				if (map[i][j][k] == 1) {
					q.push({ i,{j,k} });
					check[i][j][k] = true;
				}
			}

	int answer = -1;
	while (!q.empty()) {
		++answer;

		int size = q.size();
		while (size--) {
			int tz = q.front().first;
			int ty = q.front().second.first;
			int tx = q.front().second.second;
			q.pop();

			int dir[9][3] = { {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} };
			for (int i = 0; i < 9; i++) {
				int nx = tx + dir[i][0], ny = ty + dir[i][1], nz = tz + dir[i][2];
				if (nx < 0 || nx >= M || ny < 0 || ny >= N || nz < 0 || nz >= H)
					continue;
				if (check[nz][ny][nx] || map[nz][ny][nx])
					continue;

				q.push({ nz,{ny, nx} });
				check[nz][ny][nx] = true;
				map[nz][ny][nx] = 1;
			}
		}
	}

	for (int k = 0; k < H; k++)
		for (int j = 0; j < N; j++)
			for (int i = 0; i < M; i++)
				if (!map[k][j][i]) {
					cout << -1;
					return 0;
				}
	cout << answer;
}

 

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

#include <iostream>
#include <queue>
using namespace std;

bool checked[100001];

int main(void)
{
	int n, k;
	cin >> n >> k;

	int ans = -1;
	queue<int> q;
	q.push(n);
	checked[n] = true;
	while (!q.empty()) {
		ans++;

		int s = q.size();
		while (s--) {
			int x = q.front();
			q.pop();

			if (x == k) {
				cout << ans;
				return 0;
			}

			int dx[3] = { x + 1, x - 1, x * 2 };
			for (int i = 0; i < 3; i++)
				if (0 <= dx[i] && dx[i] <= 100000 && !checked[dx[i]]) {
					q.push(dx[i]);
					checked[dx[i]] = true;
				}
		}
	}
}

 

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

 

1726번: λ‘œλ΄‡

λ§Žμ€ 곡μž₯μ—μ„œ λ‘œλ΄‡μ΄ 이용되고 μžˆλ‹€. 우리 μ›”λ“œ 곡μž₯의 λ‘œλ΄‡μ€ λ°”λΌλ³΄λŠ” λ°©ν–₯으둜 ꢀ도λ₯Ό 따라 움직이며, μ›€μ§μ΄λŠ” λ°©ν–₯은 동, μ„œ, 남, 뢁 κ°€μš΄λ° ν•˜λ‚˜μ΄λ‹€. λ‘œλ΄‡μ˜ 이동을 μ œμ–΄ν•˜λŠ” λͺ…λ Ήμ–΄λŠ”

www.acmicpc.net

#include <iostream>
#include <queue>
using namespace std;

int M, N;
int startX, startY, startDir;
int endX, endY, endDir;
int map[101][101], check[101][101][5];
int dir[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };

void Input()
{
	cin >> M >> N;
	for (int i = 1; i <= M; ++i)
		for (int j = 1; j <= N; ++j)
			cin >> map[i][j];
	cin >> startY >> startX >> startDir >> endY >> endX >> endDir;
}

int Solution()
{
	int answer = 10e9;

	queue<pair<pair<int, int>, int>> q;
	q.push({ {startY, startX}, startDir });

	while (!q.empty()) {
		int ty = q.front().first.first, tx = q.front().first.second, td = q.front().second;
		q.pop();

		if (ty == endY && tx == endX && td == endDir)
		{
			answer = min(answer, check[endY][endX][endDir]);
			continue;
		}

		for (int k = 1; k <= 3; ++k)
		{
			int ny = ty + dir[td - 1][0] * k, nx = tx + dir[td - 1][1] * k;
			if (ny <= 0 || ny > M || nx <= 0 || nx > N || map[ny][nx])
				break;

			if (check[ny][nx][td] == 0 || check[ny][nx][td] > check[ty][tx][td] + 1)
			{
				check[ny][nx][td] = check[ty][tx][td] + 1;
				q.push({ {ny,nx},td });
			}
		}

		for (int nd = 1; nd <= 4; ++nd)
		{
			int rot = 1;
			if (nd == td) rot = 0;
			else if (nd == 1 && td == 2) rot = 2;
			else if (nd == 2 && td == 1) rot = 2;
			else if (nd == 3 && td == 4) rot = 2;
			else if (nd == 4 && td == 3) rot = 2;

			if (check[ty][tx][nd] == 0 || check[ty][tx][nd] > check[ty][tx][td] + rot)
			{
				check[ty][tx][nd] = check[ty][tx][td] + rot;
				q.push({ {ty,tx},nd });
			}
		}
	}

	return answer;
}

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

	Input();
	cout << Solution();
}
μ €μž‘μžν‘œμ‹œ (μƒˆμ°½μ—΄λ¦Ό)
'πŸ“ Computer Science/✏ Algorithm' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • [C++] λΉ„νŠΈ μ—°μ‚°μž
  • [C++] μ΅œλ‹¨ 경둜(λ‹€μ΅μŠ€νŠΈλΌ, ν”Œλ‘œμ΄λ“œ 와샬, 벨만 ν¬λ“œ)
  • [C++] 동적 κ³„νšλ²•(Dynamic Programming)
  • [C++] 덱(Deque)
Blxxming
Blxxming
CS 지식과 κ³΅λΆ€ν•˜λ‹€ 배운 것, κ²½ν—˜ν•œ 것 등을 κΈ°λ‘ν•˜λŠ” λΈ”λ‘œκ·Έμž…λ‹ˆλ‹€.
  • Blxxming
    πŸ’‘λ²ˆλœ©πŸ’‘
    Blxxming
  • 전체
    였늘
    μ–΄μ œ
  • 곡지사항

    • Tech Interview
    • πŸ“š Tech (246)
      • πŸ“ Computer Science (96)
        • ✏ OS (12)
        • ✏ Network & Web (10)
        • ✏ Database (11)
        • ✏ Data Structure (6)
        • ✏ Algorithm (40)
        • ✏ Design Pattern (9)
        • ✏ Cloud Computing (3)
        • ✏ (5)
      • πŸ“ Language (73)
        • ✏ Language (6)
        • ✏ C & C++ (11)
        • ✏ C# (19)
        • ✏ JAVA (37)
      • πŸ“ Game (43)
        • ✏ Computer Graphics (2)
        • ✏ Unity (14)
        • ✏ Unreal (26)
        • ✏ (1)
      • πŸ“ Book (34)
        • ✏ Effective (3)
        • ✏ Game Server (16)
        • ✏ Clean Code (14)
        • ✏ (1)
  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.0
Blxxming
[C++] 깊이 μš°μ„  탐색(DFS), λ„ˆλΉ„ μš°μ„  탐색(BFS)
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”