백준 4963 섬의 개수

2020. 9. 9. 21:32·알고리즘/BOJ

www.acmicpc.net/problem/4963

 

4963번: 섬의 개수

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다. 둘째 줄부터 h개 줄에는 지도�

www.acmicpc.net

BFS와 DFS를 연습하기에 좋은 간단한 문제였다.

주의해야 할 점이 있다면 상하좌우뿐만 아니라 대각선에도 땅이 있다면 섬으로 연결시켜줘야 한다.

 

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

int ar[51][51];
bool vis[51][51];
int dx[8] = { 0,0,1,-1,-1,1,-1,1 };
int dy[8] = { 1,-1,0,0,-1,-1,1,1 };

int main() {
	int w, h, cnt = 0;
	queue<pair<int, int>> Q;
	while (1) {
		cin >> w >> h;
		if (w == 0 && h == 0) break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> ar[i][j];
			}
		}

		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				if (vis[i][j] || ar[i][j] == 0) continue;
				Q.push({ i,j }); vis[i][j] = true; cnt++;
				while (!Q.empty()) {
					auto cur = Q.front(); Q.pop();
					for (int i = 0; i < 8; i++) {
						int nx = cur.first + dx[i];
						int ny = cur.second + dy[i];
						if (nx < 0 || nx >= h || ny < 0 || ny >= w) continue;
						if (vis[nx][ny] || ar[nx][ny] == 0) continue;
						Q.push({ nx,ny }); vis[nx][ny] = true; 
					}
				}
			}
		}
		cout << cnt << '\n';
		cnt = 0;
		for (int i = 0; i < 51; i++) {
			fill(ar[i], ar[i] + 51, 0);
			fill(vis[i], vis[i] + 51, false);
		}
	}
	return 0;
}

맵을 입력 받고 땅인 것들만 큐에 넣어주고 bfs를 돌린다 끝날 때마다 초기화해주는 것을 잊지 말자.

 

#include <iostream>
using namespace std;
	
int w, h, cnt;
int ar[51][51];
bool vis[51][51];
int dx[8] = { 0,0,1,1,1,-1,-1,-1 };
int dy[8] = { 1,-1,-1,0,1,-1,0,1 };

void dfs(int x, int y) {
	vis[x][y] = true;
	for (int i = 0; i < 8; i++) {
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx >= 0 && nx < h && ny >= 0 && ny < w) {
			if (ar[nx][ny] && !vis[nx][ny]) {
				vis[nx][ny] = true; dfs(nx, ny);
			}
		}
	}
}

int main() {
	while (1) {
		cin >> w >> h;
		if (!w && !h) break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> ar[i][j];
			}
		}
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				if (!vis[i][j] && ar[i][j]) {
					dfs(i, j); cnt++;
				}
			}
		}
		cout << cnt << '\n';
		cnt = 0;
		for (int i = 0; i < 51; i++) {
			fill(ar[i], ar[i] + 50, 0);
			fill(vis[i], vis[i] + 50, false);
		}
	}
	return 0;
}

 

dfs코드 또한 크게 다를 것 없었다.

 

 

'알고리즘 > BOJ' 카테고리의 다른 글

백준 2146 다리 만들기  (0) 2020.09.10
백준 9466 텀 프로젝트  (0) 2020.09.09
백준 2331 반복수열  (0) 2020.09.08
백준 10451 순열 사이클  (0) 2020.09.07
백준 13305 주유소  (0) 2020.09.07
'알고리즘/BOJ' 카테고리의 다른 글
  • 백준 2146 다리 만들기
  • 백준 9466 텀 프로젝트
  • 백준 2331 반복수열
  • 백준 10451 순열 사이클
khyu2
khyu2
  • khyu2
    dev log
    khyu2
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘
        • BOJ
        • Programmers
        • Algorithm
        • SWEA
      • 개발
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    시뮬레이션
    MST
    구현
    다익스트라
    우선순위 큐
    큐
    트리
    행렬 제곱
    크루스칼
    dfs
    분할 정복
    BOJ
    완전 탐색
    알고리즘
    프로그래머스
    피보나치 수
    이분 탐색
    피사노 주기
    코딩테스트 연습
    냅색
    완전탐색
    dp
    조합
    GREEDY
    BFS
    팰린드롬
    유니온 파인드
    SWEA
    이분탐색
    소수
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khyu2
백준 4963 섬의 개수
상단으로

티스토리툴바