BOJ

[백준 3019번 / java] 테트리스

syj0522 2024. 6. 29. 01:48

문제

3019번: 테트리스 (acmicpc.net)

 

풀이

생각보다 푸는 데 시간이 오래 걸린 구현문제.

블록의 밑바닥 모양과 필드의 바닥 모양을 비교해서 동일하면 count해준다. 

블록별로 카운트하는 함수를 따로 만들다가 반복되는 부분을 별도의 함수로 선언하였다.

 

dup(num) : 연속된 num개의 숫자가 최대 몇 개 있는지 확인

comp2(x) : 연속된 두 개의 숫자가 x만큼 차이나는지 확인

comp3(x, y) : 연속된 세 개의 숫자가차례로  x, y만큼 차이나는지 확인

 

다른 풀이를 보니 블럭 모양을 3차원 배열 또는 2차원 배열+string으로 선언해두고

해당 길이나 문자열 요소를 가져다 쓰는 식으로 구현하고 있었다. 

 

나는 블럭 별로 가능한 모든 경우를 직접 대입해주었기 때문에 시간이 더 오래 걸린 듯하다.

코드1

import java.util.*;
import java.io.*;

public class Main {
    static int C;
    static int[] c;
    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;
        st = new StringTokenizer(br.readLine());
        C = Integer.parseInt(st.nextToken());
        int P = Integer.parseInt(st.nextToken());
        
        c = new int[C]; //바닥 높이 저장
        st = new StringTokenizer(br.readLine());
        for(int i=0; i<C; i++){
            c[i] = Integer.parseInt(st.nextToken());
        }

        int result = 0;
        switch(P){
            case 1:
                result = op1();
                break;
            case 2:
                result = op2();
                break;
            case 3:
                result = op3();
                break;
            case 4:
                result = op4();
                break;
            case 5:
                result = op5();
                break;
            case 6:
                result = op6();
                break;
            case 7:
                result = op7();
                break;
            default: break;
        }
        bw.write(result + " ");
        bw.flush();
        bw.close();
    }
    static int op1(){
        //t
        int ans = C; //바닥 길이 1
        //t t t t
        ans += dup(4);
        return ans;
    }
    static int op2(){
        int ans = 0;
        //t t
        ans += dup(2);
        return ans;
    }
    static int op3(){
        int ans = 0;
        //t t t+1
        ans += comp3(0, 1);
        //t t-1
       ans += comp2(-1);
        return ans;
    }
    static int op4(){
        int ans = 0;
        //t+1 t t
        ans += comp3(1, 0);
        //t t+1
        ans += comp2(1);
        return ans;
    }
    static int op5(){
        int ans = 0;
        //t t t
        ans += dup(3);
        //t t-1
        ans += comp2(-1);
        //t t-1 t
        ans += comp3(1, 1);
        //t t+1
        ans += comp2(1);
        return ans;
    }
    static int op6(){
        int ans = 0;
        //t t t
        ans += dup(3);
        //t t-2
        ans += comp2(-2);
        //t t+1 t+1
        ans += comp3(-1, 0);
        //t t
        ans += dup(2);
        return ans;
    }
    static int op7(){
        int ans = 0;
        //t t t
        ans += dup(3);
        //t t+2
        ans += comp2(2);
        //t t t-1
        ans += comp3(0, -1);
        //t t
        ans += dup(2);
        return ans;
    }
    static int dup(int num){
        //동일한 num개의 숫자가 연속
        int ans = 0;
        int count = 1;
        for(int i=1; i<C; i++){
            if(c[i] == c[i-1]){
                count++;
            }else{
                count = 1;
            }
            if(count >= num)
                ans += 1;
        }
        return ans;
    }
    static int comp2(int x){
        int ans = 0;
        for(int i=1; i<C; i++) {
            if (c[i - 1] + x == c[i]) {
                ans++;
            }
        }
        return ans;
    }
    static int comp3(int x, int y){
        int ans = 0;
        for(int i=1; i<C-1; i++){
            if(c[i-1] == c[i] + x && c[i] + y == c[i+1]){
                ans++;
            }
        }
        return ans;
    }
}

 

코드 2 

출처: 79893177번 소스 코드 (acmicpc.net)

import java.util.*;

public class Main {

    static int C, P;
    static int[] arr;
    static int cnt = 0;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        C = sc.nextInt();
        P = sc.nextInt();
        arr = new int[C];
        for (int i = 0; i < C; i++) {
            arr[i] = sc.nextInt();
        }

        String[][] blocks = {
                {"0", "0000"}, // ㅣ
                {"00"},        // ㅁ
                {"001", "10"}, // \Z
                {"100", "01"}, // Z
                {"000", "01", "101", "10"}, // ㅗ ㅏ ㅜ ㅓ
                {"000", "00", "011", "20"}, // \ㄴ
                {"000", "02", "110", "00"}  // ㄴ
        };

        for (String pattern : blocks[P - 1]) {
            count(pattern);
        }

        System.out.println(cnt);
    }

    private static void count(String block) {
        int len = block.length();
        for (int i = 0; i <= C - len; i++) {
            boolean check = true;
            for (int j = 0; j < len - 1; j++) {
                if (block.charAt(j) - block.charAt(j + 1) != arr[i + j] - arr[i + j + 1]) {
                    check = false;
                    break;
                }
            }
            if (check) cnt++;
        }
    }
}