728x90
반응형

링크

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

 

11438번: LCA 2

첫째 줄에 노드의 개수 N이 주어지고, 다음 N-1개 줄에는 트리 상에서 연결된 두 정점이 주어진다. 그 다음 줄에는 가장 가까운 공통 조상을 알고싶은 쌍의 개수 M이 주어지고, 다음 M개 줄에는 정

www.acmicpc.net

해설


이 문제는 DFS와 BFS 모두 사용할 수 있습니다.

그러나 BFS 가 메모리도 적게사용하고 시간도 약간 더 빨라 해설에서는 BFS를 사용하였습니다.

DFS버전이 궁금하시면 >> 깃허브 << 에 올려두었습니다.

 

 

골드문제에서는 주로 정적배열만으로 해결이 다 됬었는데 플레티넘으로 넘어가니 동적배열을 사용해야하네요.

2차원 vector 을 이용해서 각 노드별로 연결된 노드들의 숫자를 다 입력해둡니다.

 

그 후 BFS 를 이용해서 각 노드들의 깊이(depth) 를 구합니다.

 

골드문제인 11437 LCA 는 그냥 깊이를 맞추고 상승시켜가면서 같은걸 찾으면 되지만

이 문제같은 경우는 훨씬 노드가 많기때문에 O(N) 의 복잡도를 이용하면 시간초과가 나게됩니다.

보통 O(N) 보다 더 낮은 시간복잡도를 가지려면 이분탐색을 이용하는데 여기도 똑같습니다.

 

PARENT 배열에 각 노드의 2^0 , 2^1 , 2^2 , ... 위의 노드들을 저장해 두고 사용합니다.

이렇게 탐색을 하면 O(log N) 만에 찾을 수 있습니다.

 

코드를 보시면

PARENT[next][i] = PARENT[PARENT[next][i - 1]][i - 1]

위와 같은 코드를 보실 수 있는데

이코드의 의미는 현재 노드의 2^i 위의 부모는 2^(i - 1) 위 부모의 2^(i - 1) 위 부모와 같다는 뜻입니다.

그림과 같이 4 위의 노드는 2위의 노드의 2위 노드 와 같다는 것이죠.

그렇게 모든 2^i 위 노드들을 다 구해두고 입력이 들어올 때 마다 LCA 함수를 이용해서 값을 구해줍니다.

 

두 값의 깊이를 또 이분탐색을 이용해서 더 얕은것에 맞춰주고 아까 구해뒀던 PARENT 배열을 이용해

LCA 를 찾을 때 까지 이동을 하다가 찾으면 return 하면됩니다.

 

코드에 모두 구현되어있습니다.

 

코드

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

int N, M, DEP[100001], PARENT[100001][18];
bool visit[100001];
vector<vector<int>> LIST;
queue<int> que;

int LCA(int _a, int _b) {
	if (DEP[_a] < DEP[_b]) swap(_a, _b);

	int looper = 0;
	while (DEP[_a] != DEP[_b]) {
		++looper;
		if ((DEP[_a] - (1 << looper)) < DEP[_b]) {
			_a = PARENT[_a][looper - 1];
			looper = 0;
		}
	}
	while (_a != _b) {
		looper = 1;
		while (PARENT[_a][looper] != PARENT[_b][looper])
			++looper;
		_a = PARENT[_a][looper - 1];
		_b = PARENT[_b][looper - 1];
	}
	return _a;
}

void BFS() {
	que.push(1);
	while (!que.empty()) {
		int now = que.front();
		que.pop();
		for (int i = 0; i < LIST[now].size(); ++i) {
			int next = LIST[now][i];
			if (visit[next])
				continue;
			visit[next] = true;
			que.push(next);
			DEP[next] = DEP[now] + 1;
			PARENT[next][0] = now;
			for (int i = 1; i < 18; ++i) {
				PARENT[next][i] = PARENT[PARENT[next][i - 1]][i - 1];
			}
		}
	}
}

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

	cin >> N;
	LIST.resize(N + 1);
	for (int i = 0; i < N - 1; ++i) {
		int a, b;
		cin >> a >> b;
		LIST[a].push_back(b);
		LIST[b].push_back(a);
	}

	DEP[1] = 1;
	visit[1] = true;
	BFS();

	cin >> M;
	for (int i = 0; i < M; ++i) {
		int a, b;
		cin >> a >> b;
		cout << LCA(a, b) << "\n";
	}

	return 0;
}



728x90
반응형
728x90
반응형

링크

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

 

12015번: 가장 긴 증가하는 부분 수열 2

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

www.acmicpc.net

해설


어떤 분류의 문제다 라고 딱 설명드리기 어려운 문제입니다.

문제를 푸는 키 알고리즘은 아니긴 한데 lower_bound라는 이분 탐색을 이용해서 위치를 찾긴 합니다.

 

알고리즘은 다음과 같습니다.

1. 입력을 받습니다.

2. 입력받은 값이 현제 리스트의 끝값보다 작거나 같으면 lower_bound를 이용해 찾은 곳에 덮어 씌웁니다.

3. 입력받은 값이 현제 리스트의 끝 값보다 크면 리스트 뒤에 추가합니다.

 

알고리즘만 보면 이게 뭐 하는 건지 싶습니다.

간단하게 설명을 드리자면 배열을 하나 사용하고 증가하는 부분 수열을 계속 덮어 씌우다가

결국 튀어나가면 그때가 최대 크기의 수열인 것입니다.

간단한 예를 들어보겠습니다.

10, 50, 60, 20, 30, 40, 50

위의 예를 알고리즘을 적용하면

3번째인 60까지는 위와 같이 순차적으로 쌓이게 됩니다.

그런데 이때 이 예의 가장 긴 증가하는 부분 수열인 10 20 30 40 50 의 뒷 파트 20 30 40 50 이 들어오는 것을 잘 보시면

 

 

마치 원래 있던 수열 10 50 60 을 덮어쓰는 것처럼 보이게 됩니다.

이게 핵심입니다.

 

이 배열에 계속 후보가 될만한 것들을 덮어 씌우다가 결국 맨 마지막에 수열의 크기를 측정하면

입력에서 나올 수 있는 가장 긴 증가하는 부분 수열이 되는 것입니다.

 

 

모두 코드에 구현되어있습니다.

코드는 배열이 비어있다는 예외를 없애기 위해서 0번째에 가장 작은 값 0을 삽입하였습니다.

배열 대신 vector을 사용해서 구현해도 됩니다.

그러면 정답은 vector.size() - 1 이 됩니다. ( 맨 앞에 0을 넣으므로 )

 

코드

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

int N, TABLE[1000001], idx = 0;

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

	cin >> N;
	TABLE[0] = 0;
	for (int i = 0; i < N; ++i) {
		int temp;
		cin >> temp;

		if (temp <= TABLE[idx])
			*lower_bound(TABLE, TABLE + idx, temp) = temp;
		else
			TABLE[++idx] = temp;
	}

	cout << idx;

	return 0;
}



728x90
반응형

'컴퓨터공학 > 백준' 카테고리의 다른 글

[백준][2252][C++] 줄 세우기  (0) 2021.07.15
[백준][11438][C++] LCA 2  (0) 2021.07.14
[백준][1707][C++] 이분 그래프  (0) 2021.07.12
[백준][1717][C++] 집합의 표현  (0) 2021.07.12
[백준][1202][C++] 보석 도둑  (0) 2021.07.11
728x90
반응형

링크

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

 

1707번: 이분 그래프

입력은 여러 개의 테스트 케이스로 구성되어 있는데, 첫째 줄에 테스트 케이스의 개수 K(2≤K≤5)가 주어진다. 각 테스트 케이스의 첫째 줄에는 그래프의 정점의 개수 V(1≤V≤20,000)와 간선의 개수

www.acmicpc.net

해설


해설에 앞서 이분 그래프란?

인접한 vertex의 색이 모두 다르게 칠하는데 단 2가지 색으로만 칠할 수 있는 그래프를 말합니다.

한마디로 특정 버텍스에서 어떤 곳으로 든 이동시 퐁 당 퐁 당 이 되어야 한다는 뜻입니다.

 

핵심은 BFS를 이용하는 것입니다.

위의 설명대로 퐁 당 퐁 당 이 되어야 하기 때문에 BFS로 탐색 시 임의 값 0, 1 이 번갈아 나오면 됩니다.

 

알고리즘을 정리하면

1. BFS 를 실시하는데 연결된 모든 vertex의 value는 현재 vertex의 value와 다른 값이 되어야 한다.

2. 모든 vertex에 대해 BFS를 실시하였음에도 불구하고 모두 만족하면 YES 아니면 NO

 

아래 코드에 모두 구현되어있다.

 

코드의 경우 방문하지 않은 곳은 -1  방문할 경우 각 위치에 맞는 value 인 0 or 1 이 들어가게 된다.

vertex 방문 시 항상 인접한 모든 vertex를 검사해서 내 value와 다른지 확인한다.

 

코드

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

int K, V, E;

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

	cin >> K;

	for (int i = 0; i < K; ++i) {
		cin >> V >> E;
		vector <vector <int>> v(V, vector<int>());
		vector <int> table(V, -1);
		for (int j = 0; j < E; ++j) {
			int a, b;
			cin >> a >> b;
			a--; b--;
			v[a].push_back(b);
			v[b].push_back(a);
		}
		queue <pair <int, int>> que;
		que.push({ 0, 0 });
		while (true) {
			while (!que.empty()) {
				int vtx = que.front().first, value = que.front().second;
				if (table[vtx] != -1) {
					if (table[vtx] != value)
						break;
					else {
						que.pop();
						continue;
					}
				}
				que.pop();
				table[vtx] = value;
				value = value == 0 ? 1 : 0;
				for (int j = 0; j < v[vtx].size(); ++j)
					que.push({ v[vtx][j] , value });
			}
			if (!que.empty()) {
				cout << "NO" << "\n";
				break;
			}
			else {
				int i = 0;
				for (; i < V; ++i) {
					if (table[i] == -1)
						break;
				}
				if (i == V) {
					cout << "YES" << "\n";
					break;
				}
				que.push({ i, 0 });
				
			}
		}
		
	}

	return 0;
}



728x90
반응형
728x90
반응형

링크

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

 

1717번: 집합의 표현

첫째 줄에 n(1 ≤ n ≤ 1,000,000), m(1 ≤ m ≤ 100,000)이 주어진다. m은 입력으로 주어지는 연산의 개수이다. 다음 m개의 줄에는 각각의 연산이 주어진다. 합집합은 0 a b의 형태로 입력이 주어진다. 이는

www.acmicpc.net

해설


tree의 root를 이용해서 집합을 구별하는 문제입니다.

이 문제는 알면 쉬우나 모르면 발상을 해내는 것이 어려운 문제입니다.

 

처음에는 단순히 tree의 root를 계속 바꿔주면서 했더니 타임아웃이 났습니다.

그래서 root 를 찾을 때 찾아 올라가면서 들렸던 모든 수들의 현재 상위 노드 또한 root로 바꿔주었습니다.

 

알고리즘은 다음과 같습니다. ( a = 왼쪽 값 , b = 오른쪽 값)

입력이 0 일때

1. a의 root를 찾습니다.

2. b의 root 를 찾고 b의 root 를 a의 root로 연결시킵니다.

 (이때 각 root를 찾는 동안 들렸던 노드들의 상위 노드 또한 각자의 root로 갱신시켜줍니다.)

 

입력이 1 일 때

1. a의 root와 b의 root 가 같은지 확인합니다.

 

코드

#include <iostream>
using namespace std;

int N, M, TABLE[1000001];

int find_top(int _num) {
	if (TABLE[_num] == _num)
		return _num;
	return TABLE[_num] = find_top(TABLE[_num]);
}

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

	for (int i = 0; i <= N; ++i)
		TABLE[i] = i;
	
	for (int i = 0; i < M; ++i) {
		int temp, a, b;
		cin >> temp >> a >> b;
		if (temp) {
			if (find_top(a) == find_top(b))
				cout << "YES" << "\n";
			else
				cout << "NO" << "\n";
		}
		else
			TABLE[find_top(b)] = find_top(a);
		
	}


	return 0;
}



728x90
반응형
728x90
반응형

링크

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

 

1202번: 보석 도둑

첫째 줄에 N과 K가 주어진다. (1 ≤ N, K ≤ 300,000) 다음 N개 줄에는 각 보석의 정보 Mi와 Vi가 주어진다. (0 ≤ Mi, Vi ≤ 1,000,000) 다음 K개 줄에는 가방에 담을 수 있는 최대 무게 Ci가 주어진다. (1 ≤ Ci

www.acmicpc.net

해설


가방에 하나씩밖에 못 넣고 여러 개의 가방이 있으므로 각 가방에 넣을 수 있는 최대의 value 를 넣으면

최적화가 되므로 그리디 하게 넣으면 됩니다.

 

1. 보석과 가방을 모두 오름차순으로 정렬해두고 priority_queue(max heap) 를 준비합니다.

2. 가방에 대해 loop 를 만들고 각 가방 차례마다 넣을 수 있는 가장 큰 보석까지 priority_queue 에 넣습니다.

3. 이때 priority_queue 에는 보석의 가치만 넣으면 되므로 가치값만 넣습니다.

4. 그러면 priority_queue 의 top에는 현재 가방에 넣을 수 있는 가장 높은 가치가 있게 됩니다.

    물론 가방에 넣을 수 있는 보석이 하나도 없을 수도 있으니 체크합니다.

5. 정답에 += 하고 pop 하는 작업을 가방 끝까지 합니다. 

 

아래 코드에 모두 구현되어있습니다.

 

코드

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

int N, K, BAG[300000];
long long ANS = 0;
pair <int, int> GEM[300000];
priority_queue <int> que;

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

	for (int i = 0; i < N; ++i)
		cin >> GEM[i].first >> GEM[i].second;
	
	for (int i = 0; i < K; ++i)
		cin >> BAG[i];

	sort(GEM, GEM + N);
	sort(BAG, BAG + K);

	int idx = 0;

	for (int i = 0; i < K; ++i) {
		while (idx < N && GEM[idx].first <= BAG[i]) {
			que.push(GEM[idx].second);
			++idx;
		}
		if (!que.empty()) {
			ANS += que.top();
			que.pop();
		}
	}

	cout << ANS;

	return 0;
}



728x90
반응형
728x90
반응형

링크

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

 

7453번: 합이 0인 네 정수

첫째 줄에 배열의 크기 n (1 ≤ n ≤ 4000)이 주어진다. 다음 n개 줄에는 A, B, C, D에 포함되는 정수가 공백으로 구분되어져서 주어진다. 배열에 들어있는 정수의 절댓값은 최대 228이다.

www.acmicpc.net

해설


4개의 배열을 2개로 만드는 작업을 해야 합니다.

1번 2번  ||  3번 4번

이때 오른쪽은 미리 합을 다 구해둔 후 2진 search 를 위해 정렬을 해둡니다.

 

다음 각 왼쪽에서 모든 경우의 수에 대해 loop 를 돌립니다.

이때 오른쪽은 이미 정렬이 되어있으므로 upper_bound lower_bound 를 이용하여 2진탐색을 합니다.

 

그 후 값의 합이 0이면 upp - low 한 값을 정답에 더해줍니다.

 

4가지 배열을 각 2개씩 나눠서 계산 횟수를 줄이는 게 주목적입니다.

 

코드

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

long long NUM = 0;
int TABLE[4][4000];

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

	for (int i = 0; i < N; ++i) {
		cin >> TABLE[0][i] >> TABLE[1][i] >> TABLE[2][i] >> TABLE[3][i];
	}

	vector <int> v;

	for (int i = 0; i < N; ++i)
		for (int j = 0; j < N; ++j)
			v.push_back(TABLE[2][i] + TABLE[3][j]);

	sort(v.begin(), v.end());

	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			int now = TABLE[0][i] + TABLE[1][j];
			int low = lower_bound(v.begin(), v.end(), -now) - v.begin();
			int upp = upper_bound(v.begin(), v.end(), -now) - v.begin();
			if (v[low] == -now) {
				NUM += upp - low;
			}
		}
	}

	cout << NUM;

	return 0;
}



728x90
반응형

'컴퓨터공학 > 백준' 카테고리의 다른 글

[백준][1717][C++] 집합의 표현  (0) 2021.07.12
[백준][1202][C++] 보석 도둑  (0) 2021.07.11
[백준][1655][C++] 가운데를 말해요  (0) 2021.07.08
[백준][1103][C++] 게임  (0) 2021.07.07
[백준][1062][C++] 가르침  (0) 2021.07.06
728x90
반응형

링크

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

 

1655번: 가운데를 말해요

첫째 줄에는 수빈이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 수빈이가 외치는 정수가 차례대로 주어진다. 정수는 -1

www.acmicpc.net

해설


사실 이 문제를 풀려면 priority queue 를 2개를 사용한다는 발상이 중요합니다.

왜냐면 우리는 가운데 숫자만 관심이 있지 그 외의 숫자는 별 관심이 없거든요.

 

왼쪽의 priority queue 는 top 이 가장 큰 수가 되게 (내림차순)

오른쪽의 priority queue 는 top 이 가장 작은 수가 되게 (오름차순)

으로 셋팅을 하고 오른쪽 큐를 기준으로 값을 넣고 빼면 됩니다.

이때 지켜야할 규칙이 있는데

1. 오른쪽 큐의 크기 >= 왼쪽 큐의 크기

2. 항상 오른쪽 큐와 왼쪽큐의 최대 크기 차이는 1

 

이 두가지를 지키면서 queue 에 push 하면 됩니다.

 

그러면 왼쪽에는 항상 중간값 보다 작은 값들이 들어가 있고

오른쪽에는 중간값보다 큰 값들이 들어가게 됩니다.

 

오른쪽 큐를 중심으로 잡았으므로

1. 크기가 같으면 짝수개이므로 왼쪽 top, 오른쪽 top 중 작은 것

2. 크기가 다르면 홀수개 이므로 오른쪽 top

이 정답이 됩니다.

 

아래의 코드에 모두 구현되어있습니다.

 

코드

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

priority_queue <int> left_que;
priority_queue <int, vector<int>, greater<int>> right_que;

int min(int _a, int _b) { return _a < _b ? _a : _b; }

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	int N, temp;
	cin >> N;
	cin >> temp;
	cout << temp << "\n";
	right_que.push(temp);

	for (int i = 1; i < N; ++i) {
		cin >> temp;

		if (left_que.size() == right_que.size()) {
			if (temp >= right_que.top()) {
				right_que.push(temp);
			}
			else {
				left_que.push(temp);
				right_que.push(left_que.top());
				left_que.pop();
			}
			cout << right_que.top() << "\n";
		}
		else {
			if (temp >= right_que.top()) {
				right_que.push(temp);
				left_que.push(right_que.top());
				right_que.pop();
			}
			else {
				left_que.push(temp);
			}
			cout << min(left_que.top(), right_que.top()) << "\n";
		}
		
	}

	return 0;
}



728x90
반응형
728x90
반응형

링크

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

 

1103번: 게임

줄에 보드의 세로 크기 N과 가로 크기 M이 주어진다. 이 값은 모두 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 보드의 상태가 주어진다. 쓰여 있는 숫자는 1부터 9까지의 자연수 또는

www.acmicpc.net

해설


DFS를 이용하는 문제입니다.

그런데 너무 무지성 DFS를 이용하면 타임아웃이 뜹니다.

바로 DFS 와 DP 를 조금 섞어서 풀어야 합니다.

 

왜 DP가 가능하냐 하면 다른 DFS문제들과는 조금 다른 점이 있습니다.

다른 문제들은 A에서 B로 갔을 때 다시 B에서 A로 가버리지 못하게 항상 검사를 했고

B는 항상 A로 가지 않았습니다.

그러나 이문제는 A에서 B로 갔을 때 다시 B에서 A로 돌아갈 수 있다는 보장이 없습니다.

즉 돌아갈 수 있게 되면 무한대 정답 -1 이 되어버립니다.

 

이러한 차이로 인해 각자의 점은 각자의 최대 갈 수 있는 횟수가 정해집니다.

알고리즘을 정리하면 한 점 A의 갈 수 있는 최대 횟수는 (다음점들의 value 들 중 가장 높은 값) + 1 입니다.

 

간단한 예를 들어보자면 백준의 예제 2번 을 사용해 보겠습니다.

1 10

2H3HH4HHH5

위와 같이 테이블이 만들어집니다.

위의 테이블에서 9번째 칸에서 이동할 수 있는 곳은 없습니다.

고로 9번에서 출발할 경우 최대 이동 횟수는 1 입니다.

5번째 칸에서 이동 가능한 곳은 9번째 칸 밖에 없습니다.

아까 9번째 칸에서 이동가능한 최대 횟수는 1로 구해뒀으니 5번째 칸의 최대 횟수는 2가 됩니다.

2번째 칸에서 이동가능한 곳은 5번째 칸 밖에 없습니다.

역시 마찬가지로 최대 횟수는 3이 됩니다.

마찬가지로 0번째 칸에서 이동 가능한 곳은 2번째 칸 밖에 없습니다.

최대 횟수는 4가 됩니다.

이렇게 계산을 완료하면 0번째 칸에서 출발해서 최대 횟수 정답은 4가 됩니다.

 

현재 설명은 down-top 방식으로 되어 있지만 이것을 반대로 top-down 으로 적용시키면

A 에서 갈 수 있는 4방위에 미리 구해둔 값이 있으면 그걸 그대로 쓰고, 없으면 계산을 실시하면 됩니다.

 

그리고 루프를 찾는 방법은 간단합니다.

똑같은 모양의 bool 테이블을 만들어서 현재 간 곳을 계속 기록하다가 만약 지나간 곳에 도달했다면

해당 위치에서 무한루프를 돌 수 있다는 것이므로 -1 을 return 합니다.

 

아래 코드에 모두 구현되어있습니다.

 

코드

#include <iostream>
using namespace std;

int N, M, TABLE[50][50], VALUE[50][50];
bool MEMORY[50][50];
int dx[4] = { 1, -1, 0, 0 };
int dy[4] = { 0, 0, 1, -1 };

int DFS(int _x, int _y) {
	if (TABLE[_y][_x] == 0) {
		return 0;
	}
	if (VALUE[_y][_x] != 0)
		return VALUE[_y][_x];
	if (MEMORY[_y][_x])
		return -1;
	MEMORY[_y][_x] = true;
	int best = 0;
	for (int i = 0; i < 4; ++i) {
		int nx = _x + dx[i] * TABLE[_y][_x];
		int ny = _y + dy[i] * TABLE[_y][_x];
		if (0 <= nx && nx < M && 0 <= ny && ny < N) {
			int value = DFS(nx, ny);
			if (value == -1)
				return -1;
			best = best > value ? best : value;

		}
	}

	MEMORY[_y][_x] = false;
	VALUE[_y][_x] = best + 1;
	return best + 1;
}

int main()
{
	scanf("%d %d", &N, &M);
	getchar();
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < M; ++j) {
			char ch = getchar();
			TABLE[i][j] = ch == 'H' ? 0 : ch - '0';
		}
		getchar();
	}
	
	printf("%d", DFS(0, 0));

	return 0;
}



728x90
반응형

+ Recent posts