[백준] 3019. 테트리스

2 분 소요

문제 링크

[백준] 3019. 테트리스


풀이 과정

구현 문제입니다.


예를 들어, 5번 블럭은 위와 같이 4개의 형태를 띌 수 있습니다. 각 모양이 각 열에 올바르게 떨어지기 위한 규칙은 아래와 같습니다.

  • 모양은 밑에 세 변 heights[i], heights[i+1], heights[i+2]가 모두 동일한 높이여야 한다.
  • 모양은 heights[i+1]이 heights[i]보다 1 커야 한다.
  • 모양은 heights[i]와 heights[i+2]가 같고, heights[i+1]은 heights[i]보다 1 작아야 한다.
  • 모양은 heights[i]가 heights[i+1]보다 1 커야 한다.


각 밑변의 상대적인 높이 차를 나타내면 위의 그림과 같이 순서대로 "000", "01", "101", "10"이 됩니다.


static int check(String s) {
    char[] delta = s.toCharArray();
    int cnt = 0;

    for (int i = 0; i <= C - s.length(); i++) {
        int diff = heights[i] - (delta[0] - '0');
        boolean possible = true;

        for (int j = i; j < i + delta.length; j++) {
            if (heights[j] - (delta[j - i] - '0') != diff) {
                possible = false;
                break;
            }
        }

        if (possible) cnt++;
    }

    return cnt;
}

check(s)는 각 좌표에서 s모양의 블럭을 떨어 뜨릴 수 있는 지 판단하고, 떨어뜨릴 수 있는 모든 경우의 수를 세어 리턴합니다.

  • 먼저 입력받은 s를 문자 배열 delta로 변환한다.
  • 가능한 시작 좌표를 설정하고, 그 좌표로부터 s 모양의 블럭을 떨어뜨릴 수 있는 지 확인한다.
    • 먼저, 블럭의 맨 왼쪽 밑변 시작 위치의 높이 차 diff를 구한다.
    • 블럭이 끝나는 우측 마지막 위치까지의 높이 차가 기존에 구한 diff와 같은지 delta 요소를 빼 확인한다.
    • 블럭 밑변 모든 조각들의 높이차가 같다면 s 모양의 블럭을 떨어뜨릴 수 있는 것이므로 cnt를 센다.


코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    static int C;
    static int[] heights;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        C = stoi(st.nextToken());
        int P = stoi(st.nextToken());
        heights = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        int cnt = 0;

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

        System.out.println(cnt);
    }

    static int check(String s) {
        char[] delta = s.toCharArray();
        int cnt = 0;

        for (int i = 0; i <= C - s.length(); i++) {
            int diff = heights[i] - (delta[0] - '0');
            boolean possible = true;

            for (int j = i; j < i + delta.length; j++) {
                if (heights[j] - (delta[j - i] - '0') != diff) {
                    possible = false;
                    break;
                }
            }

            if (possible) cnt++;
        }

        return cnt;
    }

    static int stoi(String s) {
        return Integer.parseInt(s);
    }
}

카테고리:

업데이트:

댓글남기기