BOJ11967

불켜기

문제출처

문제 해석

  • N x N 배열에서 최대로 불을 킬 수 있는 방의 개수를 구하는 문제입니다.
  • 어떤 방에서 다른 방의 불을 킬 수 있는 좌표가 주어집니다. 그리고,각 방에서는 상하좌우의 방으로 이동이 가능합니다.

설계(X)

  • 처음에 문제를 잘 이해하지 못하고 불켜는 위치만 고려해서 탐색을 했습니다. 그래서 Baarkingdog님의 블로그를 참고하였습니다.
  • 불 을 켠 후, 상하좌우로 이동을 하는데 불이 켜진 방으로만 이동이 가능합니다.
  • 또한, 불을 킨 곳에서 상하좌우 중 방문을 한 장소가 있으면 불을 킨 곳 또한 다시 탐색을 해야합니다.

구현(X)

코드
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
#define MAXN 100

struct node {
	int x;
	int y;
};
vector<node> v[MAXN][MAXN];
bool visited[MAXN][MAXN];
int used[MAXN][MAXN];

int N, M;
int idx = 0;
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
bool is_range(int x, int y) {
	if (x < 0 || y < 0 || x >= N || y >= N) return false;
	return true;
}
bool is_connected(int x, int y) {
	for (int k = 0; k < 4; k++) {
		int nx = x + dx[k];
		int ny = y + dy[k];
		if (!is_range(nx, ny)) continue;
		if (visited[nx][ny]) return 1;
	}
	return 0;
}
int bfs() {
	queue<pair<int,int> > q;
	q.push({ 0,0 });

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

		for (int i = 0; i < v[x][y].size(); i++) {
			int nx = v[x][y][i].x;
			int ny = v[x][y][i].y;
			if (visited[nx][ny]) continue;
			if (is_connected(nx, ny)) {
				visited[nx][ny] = true;
				q.push({ nx,ny });
			}
			used[nx][ny] = true;

		}
		for (int k = 0; k < 4; k++) {
			int nx = x + dx[k];
			int ny = y + dy[k];
			if (!is_range(nx, ny)) continue;
			if (!used[nx][ny] || visited[nx][ny]) continue;
			visited[nx][ny] = true;
			q.push({ nx,ny });
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			ans += (int)used[i][j];
		}
	}
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;

	for (int i = 0; i < M; i++) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		x1--;
		y1--;
		x2--;
		y2--;
		v[x1][y1].push_back({ x2,y2 });
	}
	cout << bfs() <<"\n";
	
	return 0;
}
디버깅
제출결과

마무리

  • bfs응용문제를 너무 간단하게 봤다가 큰코다친 문제입니다. 단순 bfs만으로는 원하는 곳을 모두 탐색 할 수없기 때문에 추가로 조건을 부여해야 합니다.
  • 해당 문제는 기억이 약간 흐려질 때 쯤에 무조건 다시 풀어봐야 할 문제인 것 같습니다.