본문 바로가기

백준

백준 2615 오목 (JAVA)

문제

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

 

2615번: 오목

오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호

www.acmicpc.net

코드

package com.company;

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

public class Main {

    private static int[] dr = {-1, 0, 1, 1, 1, 0, -1, -1};
    private static int[] dc = {1, 1, 1, 0, -1, -1, -1, 0};

    private static String[][] go = new String[19][19];

    private static int counter;

    private static boolean index;

    public static void main(String[] args) throws IOException {

        //입력
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 19; i++) {
            go[i] = br.readLine().split(" ");
        }

        bk:
        for (int i = 0; i < 19; i++) {
            for (int j = 0; j < 19; j++) {
                if (go[i][j].equals("1") || go[i][j].equals("2")) {
                    for (int k = 0; k < 4; k++) {
                        counter = 1;
                        //5개의 오목이 성립하는지 확인 -> check || 6목 확인 checkPrev
                        if (check(k, go[i][j], i, j) == 5 && !checkPrev(k+4, go[i][j], i, j)) {
                            i++;
                            j++;
                            sb.append(go[i-1][j-1] + "\\n" + i + " " + j);
                            index = true;
                            break bk;
                        }
                    }
                }
            }
        }

        if(index)
            System.out.println(sb.toString());
        else
            System.out.println(0);
    }

    private static int check(int k, String player, int r, int c) {
        int nr = r + dr[k];
        int nc = c + dc[k];

        if (0 <= nr && nr < 19 && 0 <= nc && nc < 19 && go[nr][nc].equals(player)) {
            counter++;
            check(k, player, nr, nc);
        } else {
            return counter;
        }
        return counter;
    }

    private static boolean checkPrev(int k, String player, int r, int c) {
        int nr = r + dr[k];
        int nc = c + dc[k];
        return 0 <= nr && nr < 19 && 0 <= nc && nc < 19 && go[nr][nc].equals(player);
    }
}

풀이

처음에는 간단하게 접근하였으나 6목(연속된 돌의 수가 6개가 될 경우에는 승리로 치지 않는다는 규칙) 때문에 고생했다. 처음에는 다음과 같이 생각하였다. 만약 공백이 아닌 위치를 기준으로 | / - \ 이렇게 하나씩 비교해가면서 확인하고 만약 5개가 연속되었다면 그중에서 왼쪽 맨위에 있는 돌의 좌표를 출력하려고 하였다. 하지만 다음과 같이 진행하니 처리하는게 생각보다 까다로웠고 결국 인터넷에서 찾아보면서 풀었다.

풀이 방식은 처음에 내가 생각한 방식과 크게 다르지 않다

 

💡 “연속된 돌의 개수가 5개를 만족하는가” 그리고 “6개 이상으로 연속되어 있지는 않은가”

 

그리고 내가 처음에 생각한 내용과는 다른점이 있는데 연속된 돌의 개수를 세는 것에 있어서 반복문으로 푸냐 혹은 재귀로 푸냐에 차이가 있다.

그리고 재귀로 풀때는 개수를 정해놓고 반복문을 통해 검사하는것이 아닌 연속된 돌이 끊길때까지 검사를 하고 반환값으로 돌의 개수를 넘겨 준다.

만약 돌의 개수가 5개라면 다음으로 해당 위치 이전에 같은 색의 돌이 존재하는지 확인한다. 그리고 확인후 만약 다른색의 돌이 있거나 아무것도 놓여있지 않으면

해당위치에서 오목이 완성되어 승리했다고 생각하고 그만둔다.