GitHubSeob

C++ / 백준 / 1245 / 농장 관리 본문

Baekjoon/Gold

C++ / 백준 / 1245 / 농장 관리

GitHubSeob 2023. 10. 15.
문제

 

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

 

1245번: 농장 관리

첫째 줄에 정수 N(1 < N ≤ 100), M(1 < M ≤ 70)이 주어진다. 둘째 줄부터 N+1번째 줄까지 각 줄마다 격자의 높이를 의미하는 M개의 정수가 입력된다. 격자의 높이는 500보다 작거나 같은 음이 아닌 정수

www.acmicpc.net

문제풀이

 

문제를 제대로 안 봐서 조금 헤맸다.

인접한 격자는 상, 하, 좌, 우의 네 방향이 아닌 대각선까지 포함하여 총 여덟 방향이다.

그리고 산봉우리는 하나의 칸일 수도 있고 여러 칸일 수도 있다.

산봉우리 격자들은 모두 같은 높이여야 하고, 그 외의 칸들은 산봉우리의 높이보다 작아야 한다.

 

우선순위 큐를 이용해 높이 기준으로 내림차순 하게끔 cmp함수를 작성했다.

그리고 BFS를 통해 인접한 칸들을 탐색한다.

 

	for (int y = 0; y < N; ++y) {
		for (int x = 0; x < M; ++x) {
			cin >> board[y][x];
			if (board[y][x] > 0) peak.push({ y,x });
		}
	}

	int answer(0);

	while (!peak.empty()) {
		int y = peak.top().first;
		int x = peak.top().second;
		peak.pop();
		if (visited[y][x] == true) continue;
		++answer;
		BFS(y, x);
	}

메인 문이다.

산봉우리의 높이가 0인 칸들은 무시해도 되므로 1 이상인 위치만 peak이라는 우선순위 큐에 저장한다.

우선순위 큐가 빌 때까지 해당 칸이 방문한 적이 없으면 BFS함수를 실행한다.

 

void BFS(int y, int x) {
	int max = board[y][x];
	queue<pii>q;
	q.push({ y,x });

	visited[y][x] = true;
	while (!q.empty()) {
		int y = q.front().first;
		int x = q.front().second;
		q.pop();

		for (int idx = 0; idx < 8; ++idx) {
			int ny = y + dy[idx];
			int nx = x + dx[idx];
			if (ny < 0 || ny >= N || nx < 0 || nx >= M) continue;
			if (visited[ny][nx] == true) continue;
			if (board[ny][nx] > max) continue;
			if (board[ny][nx] == 0) continue;
			if (board[ny][nx] > board[y][x]) continue;
			visited[ny][nx] = true;
			q.push({ ny,nx });
		}
	}
}

인자로 받은 칸이 산봉우리의 높이가 된다.

다음 칸을 탐색할 때는 범위를 벗어나면 안 되고, 방문한 적이 없어야 한다.

그리고 해당 칸의 높이가 산봉우리보다 높으면 안 되고,

0이면 안되고,

이전칸 보다 높으면 안 된다.

이러면 높이가 높은 곳부터 낮은 곳 순서로 탐색하게 된다.

 

코드
#include <bits/stdc++.h>
#define pii pair<int, int>
using namespace std;

int dy[8] = { -1,-1,-1,0,0,1,1,1 };
int dx[8] = { -1,0,1,-1,1,-1,0,1 };
vector<vector<int>>board;
vector<vector<bool>>visited;
int N, M;

struct compare {
	bool operator()(pii& c1, pii& c2) {
		return board[c1.first][c1.second] < board[c2.first][c2.second];
	}
};

priority_queue<pii, vector<pii>, compare>peak;

void BFS(int y, int x) {
	int max = board[y][x];
	queue<pii>q;
	q.push({ y,x });

	visited[y][x] = true;
	while (!q.empty()) {
		int y = q.front().first;
		int x = q.front().second;
		q.pop();

		for (int idx = 0; idx < 8; ++idx) {
			int ny = y + dy[idx];
			int nx = x + dx[idx];
			if (ny < 0 || ny >= N || nx < 0 || nx >= M) continue;
			if (visited[ny][nx] == true) continue;
			if (board[ny][nx] > max) continue;
			if (board[ny][nx] == 0) continue;
			if (board[ny][nx] > board[y][x]) continue;
			visited[ny][nx] = true;
			q.push({ ny,nx });
		}
	}
}

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

	cin >> N >> M;
	board = vector<vector<int>>(N, vector<int>(M, 0));
	visited = vector<vector<bool>>(N, vector<bool>(M, false));

	for (int y = 0; y < N; ++y) {
		for (int x = 0; x < M; ++x) {
			cin >> board[y][x];
			if (board[y][x] > 0) peak.push({ y,x });
		}
	}

	int answer(0);

	while (!peak.empty()) {
		int y = peak.top().first;
		int x = peak.top().second;
		peak.pop();
		if (visited[y][x] == true) continue;
		++answer;
		BFS(y, x);
	}

	cout << answer;
}

 

'Baekjoon > Gold' 카테고리의 다른 글

C++ / 백준 / 6156 / Cow Contest  (0) 2024.04.04
C++ / 백준 / 3020 / 개똥벌레  (0) 2024.03.28
C++ / 백준 / 13422 / 도둑  (0) 2023.10.06
C++ / 백준 / 14891 / 톱니바퀴  (1) 2023.10.04
C++ / 백준 / 14500 / 테트로미노  (0) 2023.09.21