※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 17500번 문제인 국경이다.
문제는 아래 링크를 확인하자.

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

 

입력으로 주어지는 \(N\)의 크기가 매우 작음(4 이하)을 확인하자. 실제로 \(N=4\)인 경우 좌상단 꼭짓점에서 우하단 꼭짓점으로 한 꼭짓점을 두 번 이상 경유하지 않고 이동하는 경로의 개수는 10000개도 되지 않는다.

 

따라서, 위와 같은 모든 경로를 백트래킹으로 전부 생성해보고, BFS 등으로 각 경로가 서로 다른 동물들이 다른 영역에 포함되게끔 섬을 나누는지 확인해 문제를 해결할 수 있다.

 

칸의 경계와 칸 자체를 모두 접근해야 하므로, 코드를 작성할 때 특별히 유의하여 이를 구현하자.

 

아래는 제출한 소스코드이다.

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

int N = 5;
int visited[5][5];
char board[11][11];
int dr[4] = {0,0,1,-1};
int dc[4] = {1,-1,0,0};
bool printed;
int vis[11][11];
set<char> st;
queue<pair<int, int>> que;
bool bfs(int sR, int sC) {
	st.clear();
	vis[sR][sC] = 1;
	que.push(make_pair(sR, sC));
	while (!que.empty()) {
		int r = que.front().first, c = que.front().second; que.pop();
		if (board[r][c] != '.') st.insert(board[r][c]);
		for (int i = 0; i < 4; i++) {
			int rr = r + dr[i], cc = c + dc[i];
			if (board[rr][cc]) continue;
			rr += dr[i], cc += dc[i];
			if (rr < 2 || rr >= N * 2 + 1 || cc < 2 || cc >= N * 2 + 1 || vis[rr][cc]) continue;
			vis[rr][cc] = 1;
			que.push(make_pair(rr, cc));
		}
	}
	return (st.size() <= 1);
}
void solve() {
	memset(vis, 0, sizeof(vis));
	for (int r = 2; r < N * 2 + 1; r += 2) {
		for (int c = 2; c < N * 2 + 1; c += 2) {
			if (vis[r][c]) continue;
			if (!bfs(r, c)) return;
		}
	}
	printed = 1;
	cout << "yes\n";
	for (int r = 0; r < N * 2 + 3; r++) {
		for (int c = 0; c < N * 2 + 3; c++) {
			if (c % 2 == 0 && c > 0 && c < N * 2 + 1) {
				if (board[r][c] == '-' || board[r][c] == '#') cout << board[r][c] << board[r][c] << board[r][c];
				else if (board[r][c]) cout << ' ' << board[r][c] << ' ' ;
				else cout << ' ' << ' ' << ' ';
			}
			else {
				if (board[r][c]) cout << board[r][c];
				else cout << ' ';
			}
		}
		cout << '\n';
	}
}

void func(int r, int c) {
	if (r == N && c == N) {
		if (!printed) solve();
	}
	visited[r][c] = 1;
	for (int i = 0; i < 4; i++) {
		int rr = r + dr[i], cc = c + dc[i];
		if (rr < 0 || rr > N || cc < 0 || cc > N || visited[rr][cc]) continue;
		if (i < 2) board[1 + r * 2][1 + c * 2 + dc[i]] = '-';
		else board[1 + r * 2 + dr[i]][1 + c * 2] = '|';
		func(rr, cc);
		if (i < 2) board[1 + r * 2][1 + c * 2 + dc[i]] = 0;
		else board[1 + r * 2 + dr[i]][1 + c * 2] = 0;
	}
	visited[r][c] = 0;
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;
	for (int c = 0; c < N * 2 + 3; c++) board[0][c] = board[N * 2 + 2][c] = '#';
	for (int r = 0; r < N * 2 + 3; r++) board[r][0] = board[r][N * 2 + 2] = '#';
	for (int r = 1; r < N * 2 + 3; r += 2) {
		for (int c = 1; c < N * 2 + 3; c += 2) {
			board[r][c] = '+';
		}
	}
	for (int r = 2; r < N * 2 + 1; r += 2) {
		for (int c = 2; c < N * 2 + 1; c += 2) {
			cin >> board[r][c];
		}
	}

	func(0, 0);
	if (!printed) cout << "no";
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 25984 // C++] Extended Braille  (0) 2024.08.19
[BOJ 17586 // C++] Diagonal Cut  (0) 2024.08.18
[BOJ 29779 // C++] Colliding Encoding  (0) 2024.08.16
[BOJ 19276 // C++] Magic Trick  (0) 2024.08.15
[BOJ 1471 // C++] 사탕 돌리기  (0) 2024.08.14

+ Recent posts