본문 바로가기
Problem Solving/Baekjoon

[백준] 3019 테트리스 - Brute Force / Java

by graycode 2022. 8. 7.

 문제 링크

 

3019번: 테트리스

테트리스는 C열 필드위에서 플레이하는 유명한 게임이다. 필드의 행의 수는 무한하다. 한 번 움직일 때, 아래와 같은 일곱가지 블록 중 하나를 필드에 떨어뜨릴 수 있다. 블록을 떨어뜨리기 전에

www.acmicpc.net

 

 풀이 과정

필드의 각 칸의 높이가 주어지고 특정 블록을 필드에 배치시키는 것을 구현했을 때,

블록과 블록 사이, 또는 블록과 바닥 사이 빈 공간이 없도록 배치시켜야한다.

 

이때 블럭이 밑면과 맞닿았을 때 빈 공간이 발생할 수 있는 값을 표현하면 아래와 같다.

                                 
                                 
                                 
                                 
                                 
  0   0 0   0 0 1   0 0 0   0 2  

 

예시로 높이가 2 1 1 인 필드에 문제에 제시된 4번 블럭 1 0 0배치시켰을 때는 아래와 같으며,

     
     
     

필드와 블럭의 각 자리의 수를 뺀 값이 모두 일치할 시 (2 - 1 = 1 - 0 = 1 - 0 = 1)

이 경우에서 빈 공간이 존재하지 않음을 알 수 있다.

 

이렇게 각 블럭 당 빈 공간의 값과 회전했을 때의 값을 switch 문에 모두 지정해둔 후,

필드의 각 자릿수 - 블럭의 각 자릿수의 값이 모두 일치하는 지를 검사하여

블럭을 배치시킬 수 있는 경우의 수 cnt 변수에 값을 누적시켜 정답으로써 출력한다.

 

 풀이 코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Main {

    static int c, p, cnt;
    static int[] map;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = new StringTokenizer(br.readLine());

        c = Integer.parseInt(st.nextToken());
        p = Integer.parseInt(st.nextToken());
        map = new int[c];

        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < c; i++)
            map[i] = Integer.parseInt(st.nextToken());

        switch (p) {
            case 1:
                cnt += c;
                check("0000");
                break;
            case 2:
                check("00");
                break;
            case 3:
                check("001");
                check("10");
                break;
            case 4:
                check("100");
                check("01");
                break;
            case 5:
                check("000");
                check("01");
                check("101");
                check("10");
                break;
            case 6:
                check("000");
                check("00");
                check("011");
                check("20");
                break;
            case 7:
                check("000");
                check("02");
                check("110");
                check("00");
                break;
        }

        bw.write(cnt + "\n");
        bw.flush();
    }

    private static void check(String block) {
        int len = block.length();

        for (int i = 0; i <= c - len; i++) {
            int gap = map[i] - block.charAt(0) - '0';

            boolean flag = true;
            for (int j = 1; j < len; j++) {
                if (map[i + j] - block.charAt(j) - '0' != gap) {
                    flag = false;
                    break;
                }
            }

            if (flag)
                cnt++;
        }
    }

}

댓글