Algorithm

백준 1303번 <전쟁-전투>

seungh2 2022. 12. 27. 23:10

백준 알고리즘 1303번

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

 

1303번: 전쟁 - 전투

첫째 줄에는 전쟁터의 가로 크기 N, 세로 크기 M(1 ≤ N, M ≤ 100)이 주어진다. 그 다음 두 번째 줄에서 M+1번째 줄에는 각각 (X, Y)에 있는 병사들의 옷색이 띄어쓰기 없이 주어진다. 모든 자리에는

www.acmicpc.net


1303번

전쟁이 벌어지고 있다. 병사들은 N명이 뭉쳐있을 때 N^2의 위력을 낼 수 있다.지금 전쟁터의 상황이 주어졌을 때, 아군(White)과 적군(Blue) 병사의 위력의 합을 구하여라.

 

입력으로 첫 줄에 전쟁터의 가로 크기 M과 세로 크기 N이 주어진다.

그 다음 N개의 줄에 걸쳐 전쟁터의 상황이 들어온다.

 

출력으로 아군 병사의 위력의 합과 적군 병사의 위력의 합을 출력하면 된다.


문제 해결

BFS를 이용해 해결할 수 있는 문제이다.

문제에서 가로 크기가 N, 세로 크기가 M으로 주어졌는데, 세로 크기가 N, 가로 크기가 M으로 사용하는 것이 더 편해서 바꿔서 입력받았다.

 

전쟁터의 각 위치를 기준으로 BFS를 돌리면서 인접한 같은 팀의 병사를 센다. 이때, 이전에 방문했던 위치라면 또 BFS를 돌리지 않게 하기 위해 boolean 형 2차원 배열로 방문체크를 해주었다.


코드

package boj1303;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Queue;

public class Main {
	static class Point {
		int i, j;

		public Point(int i, int j) {
			super();
			this.i = i;
			this.j = j;
		}
	}

	static int N, M;
	static char[][] Map;
	static boolean[][] visit;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] inarr = br.readLine().split(" ");
		M = Integer.parseInt(inarr[0]);	// M : Map의 가로 길이
		N = Integer.parseInt(inarr[1]);	// N : Map의 세로 길이
		Map = new char[N][];	// Map[i][j] : (i, j) 위치의 병사가 아군(W)인지 적군(B)인지
		for (int i = 0; i < N; i++) {
			Map[i] = br.readLine().toCharArray();
		}

		int white = 0;	// white : 아군의 위력
		int blue = 0;	// blue : 적군의 위력
		visit = new boolean[N][M];	// visit[i][j] : Map[i][j] 위치를 방문했는가
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				if (visit[i][j])
					continue;
				int num = bfs(new Point(i, j));
				if(Map[i][j] == 'W') {
					white += num*num;
				}else {
					blue += num*num;
				}
			}
		}
		System.out.println(white + " " + blue);
	}

	// 델타 탐색을 하기 위해 필요한 di, dj
	static int[] di = { -1, 1, 0, 0 };	
	static int[] dj = { 0, 0, -1, 1 };

	// 입력으로 위치 pnt가 들어오고
	// 출력으로 pnt를 포함하여 같은 팀 병사가 주변에 몇 명인지 
	static int bfs(Point pnt) {
		visit[pnt.i][pnt.j] = true;
		Queue<Point> Q = new ArrayDeque<>();

		int size = 1;	// size : 주변에 같은 팀의 수. 나를 포함해야하기 때문에 1부터
		Q.add(pnt);
		while (!Q.isEmpty()) {
			Point p = Q.poll();
			for (int k = 0; k < 4; k++) {
				int ni = p.i + di[k];
				int nj = p.j + dj[k];
				// 범위를 벗어나거나 이미 방문했다면 continue
				if (ni < 0 || nj < 0 || ni >= N || nj >= M || visit[ni][nj]) {
					continue;
				}
				// 같은 팀이 아니라면 continue
				if (Map[pnt.i][pnt.j] != Map[ni][nj]) {
					continue;
				}
				Q.add(new Point(ni, nj));
				visit[ni][nj] = true;
				size++;
			}
		}
		return size;
	}

}

결과

 


 

728x90