[SWEA]재미있는 오셀로 게임

onyoo·2023년 11월 12일
0

알고리즘

목록 보기
30/39

개요

하라는데로 하면 되는 문제
문제는 문제를 제대로 안읽는 나!
처음에 주어진 오셀로 게임의 첫 세팅 상태를 고려하지 않고 코드를 구성하다가 틀렸다.

이후에 세팅을 해주고 8방향을 다시 세팅해준 다음 문제를 해결했다.

문제 분석

오셀로 게임의 첫세팅 상태는 다음과 같다.
오셀로 게임의 판 크기는 4,6,8로 정해져있고 첫 세팅은 가운데 네모에 네개로 항상 이루어져있다.
이 네모의 경우,판의 크기가 유동적이기 때문에 N의 크기에 따라 설정해주면 된다.

map[N/2-1][N/2-1] = 2;
map[N/2-1][N/2] = 1;
map[N/2][N/2-1] = 1;
map[N/2][N/2] = 2;

오셀로 게임의 경우, 2 1 1 1 2 이런식으로 있을때 가운데에 있는 흑돌(1) 의 색깔이 흰돌(2)로 변경된다.

위와같은 가로세로 방향뿐만 아니라,대각선도 해당한다.

마지막으로 주어지는 입력값은 돌을 놓을 수 없는 곳은 입력으로 주어지지 않는다 는 것을 유의하자 !

++
문제를 푸는 과정에서 처음으로 생각난 방법이 dfs였다.
하나의 방향으로 맨끝까지 탐색한다음 돌을 뒤집어주면 되기 때문에 dfs가 적절하다고 생각했다.

dfs로 현재좌표가 벽에 부딪히기전에 첫 돌과 같은 색깔의 돌이 나오면 그 사이의 돌들의 색깔은 바뀐다 dfs로 재귀를 할때마다 depth가 1씩 커진다. 이말은 즉슨, depth 만큼 돌을 뒤집어주면 된다는 것이다.

하지만 벽에 부딪힐때까지 첫 돌과 같은 색의 돌이 나오지 않고 돌이 놓여져있지 않다면 다른 재귀로 향해야한다.

문제 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
/**
 * @author onyoo
 * @performance
 * @category
 * @note
 * @see
 * https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWQmA4uK8ygDFAXj
 * @since 2023/11/11
 **/
public class Solution {
    static int T,N,M;
    static int[][] map;
    static int count;
    static int[] dx = {-1,0,1,1,1,0,-1,-1};
    static int[] dy = {1,1,1,0,-1,-1,-1,0};
    static int start_x;
    static int start_y;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
 
        T = Integer.parseInt(br.readLine());
        for(int t=1;t<T+1;t++){
            st = new StringTokenizer(br.readLine()," ");
            N = Integer.parseInt(st.nextToken());
            M = Integer.parseInt(st.nextToken());
 
            //1 : 흑돌
            //2 : 백돌
            map = new int[N][N];
 
            map[N/2-1][N/2-1] = 2;
            map[N/2-1][N/2] = 1;
            map[N/2][N/2-1] = 1;
            map[N/2][N/2] = 2;
 
            for(int m=0;m<M;m++){
                st = new StringTokenizer(br.readLine()," ");
                int y = Integer.parseInt(st.nextToken()) - 1 ;
                int x = Integer.parseInt(st.nextToken()) - 1 ;
                int color = Integer.parseInt(st.nextToken());
                //돌을 놓을때마다 변화를 주어야 함
                //가로 세로 대각선 사이에 상대방의 돌이 껴있을 경우에만 내돌이 된다
                map[x][y] = color;
 
                count = 0;
                start_x = x;
                start_y = y;
 
                for(int i=0;i<8;i++){
                    dfs(x,y,map[x][y],i,0);
                }
            }
            int black = 0;
            int white = 0;
 
            for(int i=0;i<N;i++){
                for(int j=0;j<N;j++){
                    if(map[i][j] == 1) black++;
                    else if(map[i][j] == 2)white++;
                }
            }
 
            System.out.printf("#%d %d %d\n",t,black,white);
        }
    }
    static void dfs(int x,int y,int color,int d,int depth) {
 
        int nx = x + dx[d];
        int ny = y + dy[d];
 
        if(nx < 0 || ny < 0 || nx >= N || ny >= N) {
            return;
        }
        if(map[nx][ny] == 0) return;
        if(map[nx][ny] == color) {
            int sx = start_x;
            int sy = start_y;
            for(int i=0;i<depth;i++){
                sx += dx[d];
                sy += dy[d];
                map[sx][sy] = color;
            }
            return;
            //돌을 뒤집어준다
        }
 
        dfs(nx,ny,color,d,depth+1);
 
    }
 
}
profile
반갑습니다 ! 백엔드 개발 공부를 하고있습니다.

0개의 댓글