본문 바로가기
알고리즘/BOJ 풀이(JAVA)

[BOJ ]전쟁 - 전투(1303)

by Develaniper 2021. 4. 6.

www.acmicpc.net/problem/1303

 

1303번: 전쟁 - 전투

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

www.acmicpc.net

풀이날짜 : 2021/04/06

난이도 : 실버1(solved.ac참조)

문제

전쟁은 어느덧 전면전이 시작되었다. 결국 전투는 난전이 되었고, 우리 병사와 적국 병사가 섞여 싸우게 되었다.

그러나 당신의 병사들은 하얀 옷을 입고, 적국의 병사들은 파란옷을 입었기 때문에 서로가 적인지 아군인지는 구분할 수 있다.

문제는, 같은 팀의 병사들은 모이면 모일수록 강해진다는 사실이다.

N명이 뭉쳐있을 때는 N^2의 위력을 낼 수 있다. 과연 지금 난전의 상황에서는 누가 승리할 것인가? 단, 같은 팀의 병사들이 대각선으로만 인접한 경우는 뭉쳐 있다고 보지 않는다.

입력

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

출력

첫 번째 줄에 당신의 병사의 위력의 합과 적국의 병사의 위력의 합을 출력한다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main{
    static int N, M;
    static int[][] mtx;
    static int[] dx = {0,0,1,-1};
    static int[] dy = {1,-1, 0, 0};
    static int dfs(int color, int y, int x){
        int sum =1;
        mtx[y][x]=0;    // 재 탐색 방지
        for(int i =0; i<4; i++){
            int nx = x+dx[i], ny = y+dy[i];
            if(mtx[ny][nx]==color){
                sum+=dfs(color, ny, nx);
            }
        }
        return sum;
    }
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        mtx=new int[M+2][N+2];
        for (int i = 1; i <= M; i++) {
            st = new StringTokenizer(br.readLine());
            String str = st.nextToken().toString();
            for(int s = 0; s<str.length(); s++){
                if(str.charAt(s)=='W') mtx[i][s+1]= 1;
                else mtx[i][s+1]= -1;
            }
        }

        int W=0, B=0;
        for(int i =1; i<=M; i++){
            for(int j =1; j<=N; j++){
                int color  = mtx[i][j];
                if(color==0) continue;
                int x = dfs(color, i, j);
                x*=x;
                if(color==1)    // 아군
                    W+=x;
                else                // 적군
                    B+=x;   
            }
        }
        System.out.println(W+" "+B);
    }

}

풀이

단순한 DFS로 문제를 풀었다. BFS도 가능하지만 개인적으로 DFS로 구현하는 게 더 편하다.

1. 우선 mtx에 W와 B를 받는다. (나의 경우에는 int형으로 변환하여 문제를 푸는 것을 더 선호하기 때문에 W를 1 B를 -1로 바꿔줬다.

※mtx의 크기는 주어진 크기보다 2 크게(new int[M+2][N+2])하여 시작과 끝을 여유 공간으로 해놓는다. 이렇게 하면 if(0<=i && i<N) 과 같은 처리를 하지 않고 mtx[i][j]의 값만 비교해 주면된다. 기본으로 0이 들어가 있으니 mtxcolor와 다르면 처리하지 않으면 된다.

 

2. mtx[1][1]부터 mtx[M][N]까지 이중 for문을 통해 순회하며 dfs 함수를 호출하여 인접노드를 방문한다.

※이때 중복탐색이 되지 않도록 mtx[y][x]는 W와 B의 값(1, -1)이 아닌 0으로 바꿔준다.

 

 

3. 한번의 dfs가 끝나면 x에 값을 저장해 x*x를 해주고 color가 W(1)였으면 W변수에 B(-1)이었으면 B변수에 더해준다.

※이중 for문 부분의 color를 미리 저장해 두지 않고 mtx[i][j]를 통해 참조를 하면 dfs

 

4. 순회를 마쳤으면 출력하며 마무리한다.

'알고리즘 > BOJ 풀이(JAVA)' 카테고리의 다른 글

[BOJ] 바이러스(2606)  (0) 2021.04.10
[프로그래머스] 고양이와 개는 몇 마리 있을까  (0) 2021.04.09
[BOJ]음식물 피하기(1743)  (0) 2021.04.09
[BOJ ]미로 탐색(2178)  (0) 2021.04.07
[BOJ ]DFS와 BFS(1260)  (0) 2021.04.06

댓글